17
17
* Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18
18
*/
19
19
20
+ #include <linux/kernel.h>
21
+ #include <linux/module.h>
22
+ #include <linux/io.h>
20
23
#include <linux/platform_device.h>
21
24
#include <linux/clk.h>
22
25
#include <linux/delay.h>
23
26
#include <linux/usb/otg.h>
24
27
#include <linux/usb/ulpi.h>
25
28
#include <linux/slab.h>
29
+ #include <linux/usb.h>
30
+ #include <linux/usb/hcd.h>
26
31
27
32
#include <linux/platform_data/usb-ehci-mxc.h>
28
33
29
34
#include <asm/mach-types.h>
30
35
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
+
31
42
#define ULPI_VIEWPORT_OFFSET 0x170
32
43
33
44
struct ehci_mxc_priv {
34
45
struct clk * usbclk , * ahbclk , * phyclk ;
35
- struct usb_hcd * hcd ;
36
46
};
37
47
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 ;
45
49
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 ),
89
52
};
90
53
91
54
static int ehci_mxc_drv_probe (struct platform_device * pdev )
@@ -112,12 +75,6 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev)
112
75
if (!hcd )
113
76
return - ENOMEM ;
114
77
115
- priv = devm_kzalloc (& pdev -> dev , sizeof (* priv ), GFP_KERNEL );
116
- if (!priv ) {
117
- ret = - ENOMEM ;
118
- goto err_alloc ;
119
- }
120
-
121
78
res = platform_get_resource (pdev , IORESOURCE_MEM , 0 );
122
79
if (!res ) {
123
80
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)
135
92
goto err_alloc ;
136
93
}
137
94
95
+ hcd -> has_tt = 1 ;
96
+ ehci = hcd_to_ehci (hcd );
97
+ priv = (struct ehci_mxc_priv * ) ehci -> priv ;
98
+
138
99
/* enable clocks */
139
100
priv -> usbclk = devm_clk_get (& pdev -> dev , "ipg" );
140
101
if (IS_ERR (priv -> usbclk )) {
@@ -169,8 +130,6 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev)
169
130
mdelay (10 );
170
131
}
171
132
172
- ehci = hcd_to_ehci (hcd );
173
-
174
133
/* EHCI registers start at offset 0x100 */
175
134
ehci -> caps = hcd -> regs + 0x100 ;
176
135
ehci -> regs = hcd -> regs + 0x100 +
@@ -198,8 +157,7 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev)
198
157
}
199
158
}
200
159
201
- priv -> hcd = hcd ;
202
- platform_set_drvdata (pdev , priv );
160
+ platform_set_drvdata (pdev , hcd );
203
161
204
162
ret = usb_add_hcd (hcd , irq , IRQF_SHARED );
205
163
if (ret )
@@ -244,32 +202,32 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev)
244
202
static int __exit ehci_mxc_drv_remove (struct platform_device * pdev )
245
203
{
246
204
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 );
249
210
250
211
if (pdata && pdata -> exit )
251
212
pdata -> exit (pdev );
252
213
253
214
if (pdata -> otg )
254
215
usb_phy_shutdown (pdata -> otg );
255
216
256
- usb_remove_hcd (hcd );
257
- usb_put_hcd (hcd );
258
- platform_set_drvdata (pdev , NULL );
259
-
260
217
clk_disable_unprepare (priv -> usbclk );
261
218
clk_disable_unprepare (priv -> ahbclk );
262
219
263
220
if (priv -> phyclk )
264
221
clk_disable_unprepare (priv -> phyclk );
265
222
223
+ usb_put_hcd (hcd );
224
+ platform_set_drvdata (pdev , NULL );
266
225
return 0 ;
267
226
}
268
227
269
228
static void ehci_mxc_drv_shutdown (struct platform_device * pdev )
270
229
{
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 );
273
231
274
232
if (hcd -> driver -> shutdown )
275
233
hcd -> driver -> shutdown (hcd );
@@ -279,9 +237,31 @@ MODULE_ALIAS("platform:mxc-ehci");
279
237
280
238
static struct platform_driver ehci_mxc_driver = {
281
239
.probe = ehci_mxc_drv_probe ,
282
- .remove = __exit_p ( ehci_mxc_drv_remove ) ,
240
+ .remove = ehci_mxc_drv_remove ,
283
241
.shutdown = ehci_mxc_drv_shutdown ,
284
242
.driver = {
285
243
.name = "mxc-ehci" ,
286
244
},
287
245
};
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