1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright 2012 Tilera Corporation. All Rights Reserved.
7 * Tilera TILE-Gx USB EHCI host controller driver.
10 #include <linux/irq.h>
11 #include <linux/platform_device.h>
12 #include <linux/usb/tilegx.h>
13 #include <linux/usb.h>
15 #include <asm/homecache.h>
17 #include <gxio/iorpc_usb_host.h>
18 #include <gxio/usb_host.h>
20 static void tilegx_start_ehc(void)
24 static void tilegx_stop_ehc(void)
28 static int tilegx_ehci_setup(struct usb_hcd
*hcd
)
30 int ret
= ehci_init(hcd
);
35 * struct ehci_hcd *ehci = hcd_to_ehci(hcd);
36 * ehci->need_io_watchdog = 0;
38 * here, but since this is a new driver we're going to leave the
39 * watchdog enabled. Later we may try to turn it off and see
40 * whether we run into any problems.
46 static const struct hc_driver ehci_tilegx_hc_driver
= {
47 .description
= hcd_name
,
48 .product_desc
= "Tile-Gx EHCI",
49 .hcd_priv_size
= sizeof(struct ehci_hcd
),
52 * Generic hardware linkage.
55 .flags
= HCD_MEMORY
| HCD_USB2
| HCD_BH
,
58 * Basic lifecycle operations.
60 .reset
= tilegx_ehci_setup
,
63 .shutdown
= ehci_shutdown
,
66 * Managing I/O requests and associated device resources.
68 .urb_enqueue
= ehci_urb_enqueue
,
69 .urb_dequeue
= ehci_urb_dequeue
,
70 .endpoint_disable
= ehci_endpoint_disable
,
71 .endpoint_reset
= ehci_endpoint_reset
,
76 .get_frame_number
= ehci_get_frame
,
81 .hub_status_data
= ehci_hub_status_data
,
82 .hub_control
= ehci_hub_control
,
83 .bus_suspend
= ehci_bus_suspend
,
84 .bus_resume
= ehci_bus_resume
,
85 .relinquish_port
= ehci_relinquish_port
,
86 .port_handed_over
= ehci_port_handed_over
,
88 .clear_tt_buffer_complete
= ehci_clear_tt_buffer_complete
,
91 static int ehci_hcd_tilegx_drv_probe(struct platform_device
*pdev
)
94 struct ehci_hcd
*ehci
;
95 struct tilegx_usb_platform_data
*pdata
= dev_get_platdata(&pdev
->dev
);
97 int my_cpu
= smp_processor_id();
104 * Try to initialize our GXIO context; if we can't, the device
107 if (gxio_usb_host_init(&pdata
->usb_ctx
, pdata
->dev_index
, 1) != 0)
110 hcd
= usb_create_hcd(&ehci_tilegx_hc_driver
, &pdev
->dev
,
111 dev_name(&pdev
->dev
));
118 * We don't use rsrc_start to map in our registers, but seems like
119 * we ought to set it to something, so we use the register VA.
122 (ulong
) gxio_usb_host_get_reg_start(&pdata
->usb_ctx
);
123 hcd
->rsrc_len
= gxio_usb_host_get_reg_len(&pdata
->usb_ctx
);
124 hcd
->regs
= gxio_usb_host_get_reg_start(&pdata
->usb_ctx
);
128 ehci
= hcd_to_ehci(hcd
);
129 ehci
->caps
= hcd
->regs
;
131 hcd
->regs
+ HC_LENGTH(ehci
, readl(&ehci
->caps
->hc_capbase
));
132 /* cache this readonly data; minimize chip reads */
133 ehci
->hcs_params
= readl(&ehci
->caps
->hcs_params
);
135 /* Create our IRQs and register them. */
136 pdata
->irq
= irq_alloc_hwirq(-1);
142 tile_irq_activate(pdata
->irq
, TILE_IRQ_PERCPU
);
144 /* Configure interrupts. */
145 ret
= gxio_usb_host_cfg_interrupt(&pdata
->usb_ctx
,
146 cpu_x(my_cpu
), cpu_y(my_cpu
),
147 KERNEL_PL
, pdata
->irq
);
153 /* Register all of our memory. */
154 pte
= pte_set_home(pte
, PAGE_HOME_HASH
);
155 ret
= gxio_usb_host_register_client_memory(&pdata
->usb_ctx
, pte
, 0);
161 ret
= usb_add_hcd(hcd
, pdata
->irq
, IRQF_SHARED
);
163 platform_set_drvdata(pdev
, hcd
);
164 device_wakeup_enable(hcd
->self
.controller
);
169 irq_free_hwirq(pdata
->irq
);
174 gxio_usb_host_destroy(&pdata
->usb_ctx
);
178 static int ehci_hcd_tilegx_drv_remove(struct platform_device
*pdev
)
180 struct usb_hcd
*hcd
= platform_get_drvdata(pdev
);
181 struct tilegx_usb_platform_data
*pdata
= dev_get_platdata(&pdev
->dev
);
186 gxio_usb_host_destroy(&pdata
->usb_ctx
);
187 irq_free_hwirq(pdata
->irq
);
192 static void ehci_hcd_tilegx_drv_shutdown(struct platform_device
*pdev
)
194 usb_hcd_platform_shutdown(pdev
);
195 ehci_hcd_tilegx_drv_remove(pdev
);
198 static struct platform_driver ehci_hcd_tilegx_driver
= {
199 .probe
= ehci_hcd_tilegx_drv_probe
,
200 .remove
= ehci_hcd_tilegx_drv_remove
,
201 .shutdown
= ehci_hcd_tilegx_drv_shutdown
,
203 .name
= "tilegx-ehci",
207 MODULE_ALIAS("platform:tilegx-ehci");