2 * Copyright 2012 Tilera Corporation. All Rights Reserved.
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation, version 2.
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
11 * NON INFRINGEMENT. See the GNU General Public License for
16 * Tilera TILE-Gx USB EHCI host controller driver.
19 #include <linux/irq.h>
20 #include <linux/platform_device.h>
21 #include <linux/usb/tilegx.h>
22 #include <linux/usb.h>
24 #include <asm/homecache.h>
26 #include <gxio/iorpc_usb_host.h>
27 #include <gxio/usb_host.h>
29 static void tilegx_start_ehc(void)
33 static void tilegx_stop_ehc(void)
37 static int tilegx_ehci_setup(struct usb_hcd
*hcd
)
39 int ret
= ehci_init(hcd
);
44 * struct ehci_hcd *ehci = hcd_to_ehci(hcd);
45 * ehci->need_io_watchdog = 0;
47 * here, but since this is a new driver we're going to leave the
48 * watchdog enabled. Later we may try to turn it off and see
49 * whether we run into any problems.
55 static const struct hc_driver ehci_tilegx_hc_driver
= {
56 .description
= hcd_name
,
57 .product_desc
= "Tile-Gx EHCI",
58 .hcd_priv_size
= sizeof(struct ehci_hcd
),
61 * Generic hardware linkage.
64 .flags
= HCD_MEMORY
| HCD_USB2
| HCD_BH
,
67 * Basic lifecycle operations.
69 .reset
= tilegx_ehci_setup
,
72 .shutdown
= ehci_shutdown
,
75 * Managing I/O requests and associated device resources.
77 .urb_enqueue
= ehci_urb_enqueue
,
78 .urb_dequeue
= ehci_urb_dequeue
,
79 .endpoint_disable
= ehci_endpoint_disable
,
80 .endpoint_reset
= ehci_endpoint_reset
,
85 .get_frame_number
= ehci_get_frame
,
90 .hub_status_data
= ehci_hub_status_data
,
91 .hub_control
= ehci_hub_control
,
92 .bus_suspend
= ehci_bus_suspend
,
93 .bus_resume
= ehci_bus_resume
,
94 .relinquish_port
= ehci_relinquish_port
,
95 .port_handed_over
= ehci_port_handed_over
,
97 .clear_tt_buffer_complete
= ehci_clear_tt_buffer_complete
,
100 static int ehci_hcd_tilegx_drv_probe(struct platform_device
*pdev
)
103 struct ehci_hcd
*ehci
;
104 struct tilegx_usb_platform_data
*pdata
= dev_get_platdata(&pdev
->dev
);
106 int my_cpu
= smp_processor_id();
113 * Try to initialize our GXIO context; if we can't, the device
116 if (gxio_usb_host_init(&pdata
->usb_ctx
, pdata
->dev_index
, 1) != 0)
119 hcd
= usb_create_hcd(&ehci_tilegx_hc_driver
, &pdev
->dev
,
120 dev_name(&pdev
->dev
));
127 * We don't use rsrc_start to map in our registers, but seems like
128 * we ought to set it to something, so we use the register VA.
131 (ulong
) gxio_usb_host_get_reg_start(&pdata
->usb_ctx
);
132 hcd
->rsrc_len
= gxio_usb_host_get_reg_len(&pdata
->usb_ctx
);
133 hcd
->regs
= gxio_usb_host_get_reg_start(&pdata
->usb_ctx
);
137 ehci
= hcd_to_ehci(hcd
);
138 ehci
->caps
= hcd
->regs
;
140 hcd
->regs
+ HC_LENGTH(ehci
, readl(&ehci
->caps
->hc_capbase
));
141 /* cache this readonly data; minimize chip reads */
142 ehci
->hcs_params
= readl(&ehci
->caps
->hcs_params
);
144 /* Create our IRQs and register them. */
145 pdata
->irq
= create_irq();
146 if (pdata
->irq
< 0) {
151 tile_irq_activate(pdata
->irq
, TILE_IRQ_PERCPU
);
153 /* Configure interrupts. */
154 ret
= gxio_usb_host_cfg_interrupt(&pdata
->usb_ctx
,
155 cpu_x(my_cpu
), cpu_y(my_cpu
),
156 KERNEL_PL
, pdata
->irq
);
162 /* Register all of our memory. */
163 pte
= pte_set_home(pte
, PAGE_HOME_HASH
);
164 ret
= gxio_usb_host_register_client_memory(&pdata
->usb_ctx
, pte
, 0);
170 ret
= usb_add_hcd(hcd
, pdata
->irq
, IRQF_SHARED
);
172 platform_set_drvdata(pdev
, hcd
);
173 device_wakeup_enable(hcd
->self
.controller
);
178 destroy_irq(pdata
->irq
);
183 gxio_usb_host_destroy(&pdata
->usb_ctx
);
187 static int ehci_hcd_tilegx_drv_remove(struct platform_device
*pdev
)
189 struct usb_hcd
*hcd
= platform_get_drvdata(pdev
);
190 struct tilegx_usb_platform_data
*pdata
= dev_get_platdata(&pdev
->dev
);
195 gxio_usb_host_destroy(&pdata
->usb_ctx
);
196 destroy_irq(pdata
->irq
);
201 static void ehci_hcd_tilegx_drv_shutdown(struct platform_device
*pdev
)
203 usb_hcd_platform_shutdown(pdev
);
204 ehci_hcd_tilegx_drv_remove(pdev
);
207 static struct platform_driver ehci_hcd_tilegx_driver
= {
208 .probe
= ehci_hcd_tilegx_drv_probe
,
209 .remove
= ehci_hcd_tilegx_drv_remove
,
210 .shutdown
= ehci_hcd_tilegx_drv_shutdown
,
212 .name
= "tilegx-ehci",
213 .owner
= THIS_MODULE
,
217 MODULE_ALIAS("platform:tilegx-ehci");