1717 * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
1818 */
1919
20+ #include <linux/kernel.h>
21+ #include <linux/module.h>
22+ #include <linux/io.h>
2023#include <linux/platform_device.h>
2124#include <linux/clk.h>
2225#include <linux/delay.h>
2326#include <linux/usb/otg.h>
2427#include <linux/usb/ulpi.h>
2528#include <linux/slab.h>
29+ #include <linux/usb.h>
30+ #include <linux/usb/hcd.h>
2631
2732#include <linux/platform_data/usb-ehci-mxc.h>
2833
2934#include <asm/mach-types.h>
3035
36+ #include "ehci.h"
37+
38+ #define DRIVER_DESC "Freescale On-Chip EHCI Host driver"
39+
40+ static const char hcd_name [] = "ehci-mxc" ;
41+
3142#define ULPI_VIEWPORT_OFFSET 0x170
3243
3344struct ehci_mxc_priv {
3445 struct clk * usbclk , * ahbclk , * phyclk ;
35- struct usb_hcd * hcd ;
3646};
3747
38- /* called during probe() after chip reset completes */
39- static int ehci_mxc_setup (struct usb_hcd * hcd )
40- {
41- hcd -> has_tt = 1 ;
42-
43- return ehci_setup (hcd );
44- }
48+ static struct hc_driver __read_mostly ehci_mxc_hc_driver ;
4549
46- static const struct hc_driver ehci_mxc_hc_driver = {
47- .description = hcd_name ,
48- .product_desc = "Freescale On-Chip EHCI Host Controller" ,
49- .hcd_priv_size = sizeof (struct ehci_hcd ),
50-
51- /*
52- * generic hardware linkage
53- */
54- .irq = ehci_irq ,
55- .flags = HCD_USB2 | HCD_MEMORY ,
56-
57- /*
58- * basic lifecycle operations
59- */
60- .reset = ehci_mxc_setup ,
61- .start = ehci_run ,
62- .stop = ehci_stop ,
63- .shutdown = ehci_shutdown ,
64-
65- /*
66- * managing i/o requests and associated device resources
67- */
68- .urb_enqueue = ehci_urb_enqueue ,
69- .urb_dequeue = ehci_urb_dequeue ,
70- .endpoint_disable = ehci_endpoint_disable ,
71- .endpoint_reset = ehci_endpoint_reset ,
72-
73- /*
74- * scheduling support
75- */
76- .get_frame_number = ehci_get_frame ,
77-
78- /*
79- * root hub support
80- */
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 ,
87-
88- .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete ,
50+ static const struct ehci_driver_overrides ehci_mxc_overrides __initdata = {
51+ .extra_priv_size = sizeof (struct ehci_mxc_priv ),
8952};
9053
9154static int ehci_mxc_drv_probe (struct platform_device * pdev )
@@ -112,12 +75,6 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev)
11275 if (!hcd )
11376 return - ENOMEM ;
11477
115- priv = devm_kzalloc (& pdev -> dev , sizeof (* priv ), GFP_KERNEL );
116- if (!priv ) {
117- ret = - ENOMEM ;
118- goto err_alloc ;
119- }
120-
12178 res = platform_get_resource (pdev , IORESOURCE_MEM , 0 );
12279 if (!res ) {
12380 dev_err (dev , "Found HC with no register addr. Check setup!\n" );
@@ -135,6 +92,10 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev)
13592 goto err_alloc ;
13693 }
13794
95+ hcd -> has_tt = 1 ;
96+ ehci = hcd_to_ehci (hcd );
97+ priv = (struct ehci_mxc_priv * ) ehci -> priv ;
98+
13899 /* enable clocks */
139100 priv -> usbclk = devm_clk_get (& pdev -> dev , "ipg" );
140101 if (IS_ERR (priv -> usbclk )) {
@@ -169,8 +130,6 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev)
169130 mdelay (10 );
170131 }
171132
172- ehci = hcd_to_ehci (hcd );
173-
174133 /* EHCI registers start at offset 0x100 */
175134 ehci -> caps = hcd -> regs + 0x100 ;
176135 ehci -> regs = hcd -> regs + 0x100 +
@@ -198,8 +157,7 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev)
198157 }
199158 }
200159
201- priv -> hcd = hcd ;
202- platform_set_drvdata (pdev , priv );
160+ platform_set_drvdata (pdev , hcd );
203161
204162 ret = usb_add_hcd (hcd , irq , IRQF_SHARED );
205163 if (ret )
@@ -244,32 +202,32 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev)
244202static int __exit ehci_mxc_drv_remove (struct platform_device * pdev )
245203{
246204 struct mxc_usbh_platform_data * pdata = pdev -> dev .platform_data ;
247- struct ehci_mxc_priv * priv = platform_get_drvdata (pdev );
248- struct usb_hcd * hcd = priv -> hcd ;
205+ struct usb_hcd * hcd = platform_get_drvdata (pdev );
206+ struct ehci_hcd * ehci = hcd_to_ehci (hcd );
207+ struct ehci_mxc_priv * priv = (struct ehci_mxc_priv * ) ehci -> priv ;
208+
209+ usb_remove_hcd (hcd );
249210
250211 if (pdata && pdata -> exit )
251212 pdata -> exit (pdev );
252213
253214 if (pdata -> otg )
254215 usb_phy_shutdown (pdata -> otg );
255216
256- usb_remove_hcd (hcd );
257- usb_put_hcd (hcd );
258- platform_set_drvdata (pdev , NULL );
259-
260217 clk_disable_unprepare (priv -> usbclk );
261218 clk_disable_unprepare (priv -> ahbclk );
262219
263220 if (priv -> phyclk )
264221 clk_disable_unprepare (priv -> phyclk );
265222
223+ usb_put_hcd (hcd );
224+ platform_set_drvdata (pdev , NULL );
266225 return 0 ;
267226}
268227
269228static void ehci_mxc_drv_shutdown (struct platform_device * pdev )
270229{
271- struct ehci_mxc_priv * priv = platform_get_drvdata (pdev );
272- struct usb_hcd * hcd = priv -> hcd ;
230+ struct usb_hcd * hcd = platform_get_drvdata (pdev );
273231
274232 if (hcd -> driver -> shutdown )
275233 hcd -> driver -> shutdown (hcd );
@@ -279,9 +237,31 @@ MODULE_ALIAS("platform:mxc-ehci");
279237
280238static struct platform_driver ehci_mxc_driver = {
281239 .probe = ehci_mxc_drv_probe ,
282- .remove = __exit_p ( ehci_mxc_drv_remove ) ,
240+ .remove = ehci_mxc_drv_remove ,
283241 .shutdown = ehci_mxc_drv_shutdown ,
284242 .driver = {
285243 .name = "mxc-ehci" ,
286244 },
287245};
246+
247+ static int __init ehci_mxc_init (void )
248+ {
249+ if (usb_disabled ())
250+ return - ENODEV ;
251+
252+ pr_info ("%s: " DRIVER_DESC "\n" , hcd_name );
253+
254+ ehci_init_driver (& ehci_mxc_hc_driver , & ehci_mxc_overrides );
255+ return platform_driver_register (& ehci_mxc_driver );
256+ }
257+ module_init (ehci_mxc_init );
258+
259+ static void __exit ehci_mxc_cleanup (void )
260+ {
261+ platform_driver_unregister (& ehci_mxc_driver );
262+ }
263+ module_exit (ehci_mxc_cleanup );
264+
265+ MODULE_DESCRIPTION (DRIVER_DESC );
266+ MODULE_AUTHOR ("Sascha Hauer" );
267+ MODULE_LICENSE ("GPL" );
0 commit comments