1 /**
2 * drivers/usb/host/ehci-sunxi.c
3 * (C) Copyright 2010-2015
4 * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
5 * yangnaitian, 2011-5-24, create this file
6 * javen, 2011-6-26, add suspend and resume
7 * javen, 2011-7-18, move clock and power operations out from driver
8 *
9 * SoftWinner EHCI Driver
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License as
13 * published by the Free Software Foundation; either version 2 of
14 * the License, or (at your option) any later version.
15 *
16 */
17
18 #include <linux/platform_device.h>
19 #include <linux/time.h>
20 #include <linux/timer.h>
21 #include <linux/clk.h>
22 #include <linux/notifier.h>
23 #include <linux/suspend.h>
24 #include <linux/kernel.h>
25 #include <linux/module.h>
26 #include <linux/phy/phy.h>
27 #include <linux/usb.h>
28 #include <linux/usb/hcd.h>
29 #include <linux/regulator/consumer.h>
30 #include "ehci.h"
31 #include "sunxi-hci.h"
32
33 #define DRIVER_DESC "EHCI SUNXI driver"
34
35 #define SUNXI_EHCI_NAME "sunxi-ehci"
36 static const char ehci_name[] = SUNXI_EHCI_NAME;
37
38 #if IS_ENABLED(CONFIG_USB_SUNXI_EHCI0)
39 #define SUNXI_EHCI0_OF_MATCH "allwinner,sunxi-ehci0"
40 #else
41 #define SUNXI_EHCI0_OF_MATCH "null"
42 #endif
43
44 #if IS_ENABLED(CONFIG_USB_SUNXI_EHCI1)
45 #define SUNXI_EHCI1_OF_MATCH "allwinner,sunxi-ehci1"
46 #else
47 #define SUNXI_EHCI1_OF_MATCH "null"
48 #endif
49
50 #if IS_ENABLED(CONFIG_USB_SUNXI_EHCI2)
51 #define SUNXI_EHCI2_OF_MATCH "allwinner,sunxi-ehci2"
52 #else
53 #define SUNXI_EHCI2_OF_MATCH "null"
54 #endif
55
56 #if IS_ENABLED(CONFIG_USB_SUNXI_EHCI3)
57 #define SUNXI_EHCI3_OF_MATCH "allwinner,sunxi-ehci3"
58 #else
59 #define SUNXI_EHCI3_OF_MATCH "null"
60 #endif
61
62 static struct sunxi_hci_hcd *g_sunxi_ehci[4];
63 static u32 ehci_first_probe[4] = {1, 1, 1, 1};
64 static u32 ehci_enable[4] = {1, 1, 1, 1};
65 static atomic_t ehci_in_standby;
66
67 #if IS_ENABLED(CONFIG_PM)
68 static void sunxi_ehci_resume_work(struct work_struct *work);
69 #endif
70
71 int sunxi_usb_disable_ehci(__u32 usbc_no);
72 int sunxi_usb_enable_ehci(__u32 usbc_no);
73
ehci_set_interrupt_enable(const struct ehci_hcd * ehci,void __iomem * regs,u32 enable)74 static void ehci_set_interrupt_enable(const struct ehci_hcd *ehci,
75 void __iomem *regs, u32 enable)
76 {
77 ehci_writel(ehci, enable & 0x3f, (regs + EHCI_OPR_USBINTR));
78 }
79
ehci_disable_periodic_schedule(const struct ehci_hcd * ehci,void __iomem * regs)80 static void ehci_disable_periodic_schedule(const struct ehci_hcd *ehci,
81 void __iomem *regs)
82 {
83 u32 reg_val = 0;
84
85 reg_val = ehci_readl(ehci, (regs + EHCI_OPR_USBCMD));
86 reg_val &= ~(0x1<<4);
87 ehci_writel(ehci, reg_val, (regs + EHCI_OPR_USBCMD));
88 }
89
ehci_disable_async_schedule(const struct ehci_hcd * ehci,void __iomem * regs)90 static void ehci_disable_async_schedule(const struct ehci_hcd *ehci,
91 void __iomem *regs)
92 {
93 unsigned int reg_val = 0;
94
95 reg_val = ehci_readl(ehci, (regs + EHCI_OPR_USBCMD));
96 reg_val &= ~(0x1<<5);
97 ehci_writel(ehci, reg_val, (regs + EHCI_OPR_USBCMD));
98 }
99
ehci_set_config_flag(const struct ehci_hcd * ehci,void __iomem * regs)100 static void ehci_set_config_flag(const struct ehci_hcd *ehci,
101 void __iomem *regs)
102 {
103 ehci_writel(ehci, 0x1, (regs + EHCI_OPR_CFGFLAG));
104 }
105
ehci_test_stop(const struct ehci_hcd * ehci,void __iomem * regs)106 static void ehci_test_stop(const struct ehci_hcd *ehci,
107 void __iomem *regs)
108 {
109 unsigned int reg_val = 0;
110
111 reg_val = ehci_readl(ehci, (regs + EHCI_OPR_USBCMD));
112 reg_val &= (~0x1);
113 ehci_writel(ehci, reg_val, (regs + EHCI_OPR_USBCMD));
114 }
115
ehci_test_reset(const struct ehci_hcd * ehci,void __iomem * regs)116 static void ehci_test_reset(const struct ehci_hcd *ehci,
117 void __iomem *regs)
118 {
119 u32 reg_val = 0;
120
121 reg_val = ehci_readl(ehci, (regs + EHCI_OPR_USBCMD));
122 reg_val |= (0x1<<1);
123 ehci_writel(ehci, reg_val, (regs + EHCI_OPR_USBCMD));
124 }
125
ehci_test_reset_complete(const struct ehci_hcd * ehci,void __iomem * regs)126 static unsigned int ehci_test_reset_complete(const struct ehci_hcd *ehci,
127 void __iomem *regs)
128 {
129
130 unsigned int reg_val = 0;
131
132 reg_val = ehci_readl(ehci, (regs + EHCI_OPR_USBCMD));
133 reg_val &= (0x1<<1);
134
135 return !reg_val;
136 }
137
ehci_start(const struct ehci_hcd * ehci,void __iomem * regs)138 static void ehci_start(const struct ehci_hcd *ehci, void __iomem *regs)
139 {
140 unsigned int reg_val = 0;
141
142 reg_val = ehci_readl(ehci, (regs + EHCI_OPR_USBCMD));
143 reg_val |= 0x1;
144 ehci_writel(ehci, reg_val, (regs + EHCI_OPR_USBCMD));
145 }
146
ehci_is_halt(const struct ehci_hcd * ehci,void __iomem * regs)147 static unsigned int ehci_is_halt(const struct ehci_hcd *ehci,
148 void __iomem *regs)
149 {
150 unsigned int reg_val = 0;
151
152 reg_val = ehci_readl(ehci, (regs + EHCI_OPR_USBSTS)) >> 12;
153 reg_val &= 0x1;
154 return reg_val;
155 }
156
ehci_port_control(const struct ehci_hcd * ehci,void __iomem * regs,u32 port_no,u32 control)157 static void ehci_port_control(const struct ehci_hcd *ehci,
158 void __iomem *regs, u32 port_no, u32 control)
159 {
160 ehci_writel(ehci, control, (regs + EHCI_OPR_USBCMD + (port_no<<2)));
161 }
162
ehci_put_port_suspend(const struct ehci_hcd * ehci,void __iomem * regs)163 static void ehci_put_port_suspend(const struct ehci_hcd *ehci,
164 void __iomem *regs)
165 {
166 unsigned int reg_val = 0;
167
168 reg_val = ehci_readl(ehci, (regs + EHCI_OPR_PORTSC));
169 reg_val |= (0x01<<7);
170 ehci_writel(ehci, reg_val, (regs + EHCI_OPR_PORTSC));
171 }
172
ehci_test_mode(const struct ehci_hcd * ehci,void __iomem * regs,u32 test_mode)173 static void ehci_test_mode(const struct ehci_hcd *ehci,
174 void __iomem *regs, u32 test_mode)
175 {
176 unsigned int reg_val = 0;
177
178 reg_val = ehci_readl(ehci, (regs + EHCI_OPR_PORTSC));
179 reg_val &= ~(0x0f<<16);
180 reg_val |= test_mode;
181 ehci_writel(ehci, reg_val, (regs + EHCI_OPR_PORTSC));
182 }
183
__ehci_ed_test(const struct ehci_hcd * ehci,void __iomem * regs,__u32 test_mode)184 static void __ehci_ed_test(const struct ehci_hcd *ehci,
185 void __iomem *regs, __u32 test_mode)
186 {
187 ehci_set_interrupt_enable(ehci, regs, 0x00);
188 ehci_disable_periodic_schedule(ehci, regs);
189 ehci_disable_async_schedule(ehci, regs);
190
191 ehci_set_config_flag(ehci, regs);
192
193 ehci_test_stop(ehci, regs);
194 ehci_test_reset(ehci, regs);
195
196 /* Wait until EHCI reset complete. */
197 while (!ehci_test_reset_complete(ehci, regs))
198 ;
199
200 if (!ehci_is_halt(ehci, regs))
201 DMSG_ERR("%s_%d\n", __func__, __LINE__);
202
203 ehci_start(ehci, regs);
204 /* Wait until EHCI to be not halt. */
205 while (ehci_is_halt(ehci, regs))
206 ;
207
208 /* Ehci start, config to test. */
209 ehci_set_config_flag(ehci, regs);
210 ehci_port_control(ehci, regs, 0, EHCI_PORTSC_POWER);
211
212 ehci_disable_periodic_schedule(ehci, regs);
213 ehci_disable_async_schedule(ehci, regs);
214
215 /* Put port suspend. */
216 ehci_put_port_suspend(ehci, regs);
217
218 ehci_test_stop(ehci, regs);
219
220 while ((!ehci_is_halt(ehci, regs)))
221 ;
222
223 /* Test pack. */
224 DMSG_INFO("Start Host Test,mode:0x%x!\n", test_mode);
225 ehci_test_mode(ehci, regs, test_mode);
226 DMSG_INFO("End Host Test,mode:0x%x!\n", test_mode);
227 }
228
show_ed_test(struct device * dev,struct device_attribute * attr,char * buf)229 static ssize_t show_ed_test(struct device *dev,
230 struct device_attribute *attr, char *buf)
231 {
232 return sprintf(buf, "USB2.0 host test mode:\n"
233 "echo:\ntest_j_state\ntest_k_state\ntest_se0_nak\n"
234 "test_pack\ntest_force_enable\ntest_mask\n\n");
235 }
236
ehci_ed_test(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)237 static ssize_t ehci_ed_test(struct device *dev, struct device_attribute *attr,
238 const char *buf, size_t count)
239 {
240 __u32 test_mode = 0;
241 struct usb_hcd *hcd = NULL;
242 struct ehci_hcd *ehci = NULL;
243
244 if (dev == NULL) {
245 DMSG_PANIC("ERR: Argment is invalid\n");
246 return 0;
247 }
248
249 hcd = dev_get_drvdata(dev);
250 if (hcd == NULL) {
251 DMSG_PANIC("ERR: hcd is null\n");
252 return 0;
253 }
254
255 ehci = hcd_to_ehci(hcd);
256 if (ehci == NULL) {
257 DMSG_PANIC("ERR: ehci is null\n");
258 return 0;
259 }
260
261 mutex_lock(&dev->mutex);
262
263 DMSG_INFO("ehci_ed_test:%s\n", buf);
264
265 if (!strncmp(buf, "test_not_operating", 18)) {
266 test_mode = EHCI_PORTSC_PTC_DIS;
267 DMSG_INFO("test_mode:0x%x\n", test_mode);
268 } else if (!strncmp(buf, "test_j_state", 12)) {
269 test_mode = EHCI_PORTSC_PTC_J;
270 DMSG_INFO("test_mode:0x%x\n", test_mode);
271 } else if (!strncmp(buf, "test_k_state", 12)) {
272 test_mode = EHCI_PORTSC_PTC_K;
273 DMSG_INFO("test_mode:0x%x\n", test_mode);
274 } else if (!strncmp(buf, "test_se0_nak", 12)) {
275 test_mode = EHCI_PORTSC_PTC_SE0NAK;
276 DMSG_INFO("test_mode:0x%x\n", test_mode);
277 } else if (!strncmp(buf, "test_pack", 9)) {
278 test_mode = EHCI_PORTSC_PTC_PACKET;
279 DMSG_INFO("test_mode:0x%x\n", test_mode);
280 } else if (!strncmp(buf, "test_force_enable", 17)) {
281 test_mode = EHCI_PORTSC_PTC_FORCE;
282 DMSG_INFO("test_mode:0x%x\n", test_mode);
283 } else if (!strncmp(buf, "test_mask", 9)) {
284 test_mode = EHCI_PORTSC_PTC_MASK;
285 DMSG_INFO("test_mode:0x%x\n", test_mode);
286 } else {
287 DMSG_PANIC("ERR: test_mode Argment is invalid\n");
288 mutex_unlock(&dev->mutex);
289 return count;
290 }
291
292 DMSG_INFO("regs: 0x%p\n", hcd->regs);
293 __ehci_ed_test(ehci, hcd->regs, test_mode);
294
295 mutex_unlock(&dev->mutex);
296
297 return count;
298 }
299
300 static DEVICE_ATTR(ed_test, 0644, show_ed_test, ehci_ed_test);
301
show_phy_threshold(struct device * dev,struct device_attribute * attr,char * buf)302 static ssize_t show_phy_threshold(struct device *dev,
303 struct device_attribute *attr, char *buf)
304 {
305 struct sunxi_hci_hcd *sunxi_ehci = NULL;
306
307 sunxi_ehci = dev->platform_data;
308
309 return sprintf(buf, "threshold:0x%x\n",
310 usb_phyx_tp_read(sunxi_ehci, 0x2a, 2));
311 }
312
ehci_phy_threshold(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)313 static ssize_t ehci_phy_threshold(struct device *dev,
314 struct device_attribute *attr, const char *buf, size_t count)
315 {
316 struct sunxi_hci_hcd *sunxi_ehci = NULL;
317 int val = 0;
318 int err;
319
320 err = kstrtoint(buf, 16, &val);
321 if (err != 0)
322 return -EINVAL;
323
324 if (dev == NULL) {
325 DMSG_PANIC("ERR: Argment is invalid\n");
326 return 0;
327 }
328 sunxi_ehci = dev->platform_data;
329
330 if ((val >= 0) && (val <= 0x3)) {
331 usb_phyx_tp_write(sunxi_ehci, 0x2a, val, 2);
332 } else {
333 DMSG_PANIC("adjust disconnect threshold 0x%x is fail, value:0x0~0x3\n", val);
334 return count;
335 }
336
337 DMSG_INFO("adjust succeed: threshold val:0x%x, no:%x\n",
338 usb_phyx_tp_read(sunxi_ehci, 0x2a, 2),
339 sunxi_ehci->usbc_no);
340
341 return count;
342 }
343
344 static DEVICE_ATTR(phy_threshold, 0644, show_phy_threshold, ehci_phy_threshold);
345
show_phy_range(struct device * dev,struct device_attribute * attr,char * buf)346 static ssize_t show_phy_range(struct device *dev,
347 struct device_attribute *attr, char *buf)
348 {
349 struct sunxi_hci_hcd *sunxi_ehci = NULL;
350
351 sunxi_ehci = dev->platform_data;
352 #if defined(CONFIG_ARCH_SUN8IW17) | defined(CONFIG_ARCH_SUN8IW11)
353 DMSG_INFO("PHY's rate and range:0x0~0x1f\n");
354 return sprintf(buf, "rate:0x%x\n",
355 usb_phyx_tp_read(sunxi_ehci, 0x20, 5));
356 #else
357 DMSG_INFO("PHY's rate and range:0x0~0x3ff\n");
358 return sprintf(buf, "rate:0x%x\n",
359 usb_phyx_read(sunxi_ehci));
360 #endif
361 }
362
ehci_phy_range(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)363 static ssize_t ehci_phy_range(struct device *dev, struct device_attribute *attr,
364 const char *buf, size_t count)
365 {
366 struct sunxi_hci_hcd *sunxi_ehci = NULL;
367 int val = 0;
368 int err;
369
370 if (dev == NULL) {
371 DMSG_PANIC("ERR: Argment is invalid\n");
372 return 0;
373 }
374
375 err = kstrtoint(buf, 16, &val);
376 if (err != 0)
377 return -EINVAL;
378
379 sunxi_ehci = dev->platform_data;
380
381
382 #if defined(CONFIG_ARCH_SUN8IW17) || defined(CONFIG_ARCH_SUN8IW11)
383 DMSG_INFO("adjust PHY's rate and range:0x0~0x1f\n");
384 if ((val >= 0) && (val <= 0x1f)) {
385 usb_phyx_tp_write(sunxi_ehci, 0x20, val, 5);
386 } else {
387 DMSG_PANIC("adjust PHY's rate and range 0x%x is fail, value:0x0~0x1f\n", val);
388 return count;
389 }
390
391 DMSG_INFO("adjust succeed:,rate val:0x%x, no:%d\n",
392 usb_phyx_tp_read(sunxi_ehci, 0x20, 5),
393 sunxi_ehci->usbc_no);
394 #else
395 DMSG_INFO("adjust PHY's rate and range:0x0~0x3ff\n");
396 if ((val >= 0x0) && (val <= 0x3ff)) {
397 usb_phyx_write(sunxi_ehci, val);
398 } else {
399 DMSG_PANIC("adjust PHY's paraments 0x%x is fail! value:0x0~0x3ff\n", val);
400 return count;
401 }
402
403 DMSG_INFO("adjust succeed:,PHY's paraments :0x%x, no:%d\n",
404 usb_phyx_read(sunxi_ehci), sunxi_ehci->usbc_no);
405 #endif
406
407 return count;
408 }
409
410 static DEVICE_ATTR(phy_range, 0644, show_phy_range, ehci_phy_range);
411
ehci_enable_show(struct device * dev,struct device_attribute * attr,char * buf)412 static ssize_t ehci_enable_show(struct device *dev,
413 struct device_attribute *attr, char *buf)
414 {
415 struct sunxi_hci_hcd *sunxi_ehci = NULL;
416
417 if (dev == NULL) {
418 DMSG_PANIC("ERR: Argment is invalid\n");
419 return 0;
420 }
421
422 sunxi_ehci = dev->platform_data;
423 if (sunxi_ehci == NULL) {
424 DMSG_PANIC("ERR: sw_ehci is null\n");
425 return 0;
426 }
427
428 return sprintf(buf, "ehci:%d, probe:%u\n",
429 sunxi_ehci->usbc_no, sunxi_ehci->probe);
430 }
431
ehci_enable_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)432 static ssize_t ehci_enable_store(struct device *dev,
433 struct device_attribute *attr, const char *buf, size_t count)
434 {
435 struct sunxi_hci_hcd *sunxi_ehci = NULL;
436 int value = 0;
437 int err;
438
439 if (dev == NULL) {
440 DMSG_PANIC("ERR: Argment is invalid\n");
441 return 0;
442 }
443
444 sunxi_ehci = dev->platform_data;
445 if (sunxi_ehci == NULL) {
446 DMSG_PANIC("ERR: sw_ehci is null\n");
447 return 0;
448 }
449
450 ehci_first_probe[sunxi_ehci->usbc_no] = 0;
451
452 err = kstrtoint(buf, 10, &value);
453 if (err != 0)
454 return -EINVAL;
455 if (value == 1) {
456 ehci_enable[sunxi_ehci->usbc_no] = 0;
457 sunxi_ehci->hsic_enable_flag = 1;
458 sunxi_usb_enable_ehci(sunxi_ehci->usbc_no);
459
460 if (sunxi_ehci->usbc_no == HCI0_USBC_NO)
461 sunxi_set_host_vbus(sunxi_ehci, 1);
462
463 if (sunxi_ehci->hsic_ctrl_flag)
464 sunxi_set_host_hisc_rdy(sunxi_ehci, 1);
465 } else if (value == 0) {
466 if (sunxi_ehci->hsic_ctrl_flag)
467 sunxi_set_host_hisc_rdy(sunxi_ehci, 0);
468
469 ehci_enable[sunxi_ehci->usbc_no] = 1;
470 sunxi_usb_disable_ehci(sunxi_ehci->usbc_no);
471 sunxi_ehci->hsic_enable_flag = 0;
472 ehci_enable[sunxi_ehci->usbc_no] = 0;
473 } else {
474 DMSG_INFO("unknown value (%d)\n", value);
475 }
476
477 return count;
478 }
479
480 static DEVICE_ATTR(ehci_enable, 0664, ehci_enable_show, ehci_enable_store);
481
sunxi_hcd_board_set_vbus(struct sunxi_hci_hcd * sunxi_ehci,int is_on)482 static void sunxi_hcd_board_set_vbus(
483 struct sunxi_hci_hcd *sunxi_ehci, int is_on)
484 {
485 sunxi_ehci->set_power(sunxi_ehci, is_on);
486 }
487
sunxi_hcd_board_set_passby(struct sunxi_hci_hcd * sunxi_ehci,int is_on)488 static void sunxi_hcd_board_set_passby(struct sunxi_hci_hcd *sunxi_ehci,
489 int is_on)
490 {
491 sunxi_ehci->usb_passby(sunxi_ehci, is_on);
492 }
493
open_ehci_clock(struct sunxi_hci_hcd * sunxi_ehci)494 static int open_ehci_clock(struct sunxi_hci_hcd *sunxi_ehci)
495 {
496 return sunxi_ehci->open_clock(sunxi_ehci, 0);
497 }
498
close_ehci_clock(struct sunxi_hci_hcd * sunxi_ehci)499 static int close_ehci_clock(struct sunxi_hci_hcd *sunxi_ehci)
500 {
501 return sunxi_ehci->close_clock(sunxi_ehci, 0);
502 }
503
sunxi_start_ehci(struct sunxi_hci_hcd * sunxi_ehci)504 static void sunxi_start_ehci(struct sunxi_hci_hcd *sunxi_ehci)
505 {
506 open_ehci_clock(sunxi_ehci);
507 sunxi_hcd_board_set_passby(sunxi_ehci, 1);
508 sunxi_hcd_board_set_vbus(sunxi_ehci, 1);
509 }
510
sunxi_stop_ehci(struct sunxi_hci_hcd * sunxi_ehci)511 static void sunxi_stop_ehci(struct sunxi_hci_hcd *sunxi_ehci)
512 {
513 sunxi_hcd_board_set_vbus(sunxi_ehci, 0);
514 sunxi_hcd_board_set_passby(sunxi_ehci, 0);
515 close_ehci_clock(sunxi_ehci);
516 }
517
sunxi_ehci_pm_notify(struct notifier_block * nb,unsigned long mode,void * _unused)518 static int sunxi_ehci_pm_notify(struct notifier_block *nb,
519 unsigned long mode, void *_unused)
520 {
521 switch (mode) {
522 case PM_HIBERNATION_PREPARE:
523 case PM_RESTORE_PREPARE:
524 case PM_SUSPEND_PREPARE:
525 atomic_set(&ehci_in_standby, 1);
526 break;
527 case PM_POST_HIBERNATION:
528 case PM_POST_RESTORE:
529 case PM_POST_SUSPEND:
530 atomic_set(&ehci_in_standby, 0);
531 sunxi_hci_standby_completion(SUNXI_USB_EHCI);
532 break;
533 default:
534 break;
535 }
536
537 return 0;
538 }
539
540 static struct notifier_block sunxi_ehci_pm_nb = {
541 .notifier_call = sunxi_ehci_pm_notify,
542 };
543
544 static struct hc_driver sunxi_ehci_hc_driver;
545
sunxi_insmod_ehci(struct platform_device * pdev)546 int sunxi_insmod_ehci(struct platform_device *pdev)
547 {
548 struct usb_hcd *hcd = NULL;
549 struct ehci_hcd *ehci = NULL;
550 struct sunxi_hci_hcd *sunxi_ehci = NULL;
551 struct device *dev = NULL;
552 int ret = 0;
553
554 sunxi_ehci = pdev->dev.platform_data;
555 if (!sunxi_ehci) {
556 DMSG_PANIC("ERR: sunxi_ehci is null\n");
557 ret = -ENOMEM;
558 goto ERR1;
559 }
560
561 sunxi_ehci->pdev = pdev;
562 g_sunxi_ehci[sunxi_ehci->usbc_no] = sunxi_ehci;
563
564 DMSG_INFO("[%s%d]: probe, pdev->name: %s, sunxi_ehci: 0x%px, 0x:%px, irq_no:%x\n",
565 ehci_name, sunxi_ehci->usbc_no, pdev->name,
566 sunxi_ehci, sunxi_ehci->usb_vbase, sunxi_ehci->irq_no);
567
568 /* get io resource */
569 sunxi_ehci->ehci_base = sunxi_ehci->usb_vbase;
570 sunxi_ehci->ehci_reg_length = SUNXI_USB_EHCI_LEN;
571
572 /* not init ehci, when driver probe */
573 if (sunxi_ehci->usbc_no == HCI0_USBC_NO) {
574 if (sunxi_ehci->port_type != USB_PORT_TYPE_HOST) {
575 if (ehci_first_probe[sunxi_ehci->usbc_no]) {
576 ehci_first_probe[sunxi_ehci->usbc_no] = 0;
577 DMSG_INFO("[%s%d]: Not init ehci0\n",
578 ehci_name, sunxi_ehci->usbc_no);
579 return 0;
580 }
581 }
582 }
583
584 /* creat a usb_hcd for the ehci controller */
585 hcd = usb_create_hcd(&sunxi_ehci_hc_driver, &pdev->dev, ehci_name);
586 if (!hcd) {
587 DMSG_PANIC("ERR: usb_create_hcd failed\n");
588 ret = -ENOMEM;
589 goto ERR2;
590 }
591
592 hcd->rsrc_start = sunxi_ehci->usb_base_res->start;
593 hcd->rsrc_len = SUNXI_USB_EHCI_LEN;
594 hcd->regs = sunxi_ehci->ehci_base;
595 sunxi_ehci->hcd = hcd;
596
597 dev = &pdev->dev;
598 sunxi_ehci->supply = regulator_get(dev, "drvvbus");
599
600 if (IS_ERR(sunxi_ehci->supply)) {
601 DMSG_PANIC("%s()%d WARN: get supply failed\n", __func__, __LINE__);
602 sunxi_ehci->supply = NULL;
603 }
604
605 sunxi_ehci->hci_regulator = regulator_get(dev, "hci");
606 if (IS_ERR(sunxi_ehci->hci_regulator)) {
607 DMSG_PANIC("%s()%d WARN: get hci regulator failed\n", __func__, __LINE__);
608 sunxi_ehci->hci_regulator = NULL;
609 }
610 /* echi start to work */
611 sunxi_start_ehci(sunxi_ehci);
612
613 ehci = hcd_to_ehci(hcd);
614 ehci->caps = hcd->regs;
615 ehci->regs = hcd->regs +
616 HC_LENGTH(ehci, readl(&ehci->caps->hc_capbase));
617
618 /* cache this readonly data, minimize chip reads */
619 ehci->hcs_params = readl(&ehci->caps->hcs_params);
620
621 ret = usb_add_hcd(hcd, sunxi_ehci->irq_no, IRQF_SHARED);
622 if (ret != 0) {
623 DMSG_PANIC("ERR: usb_add_hcd failed\n");
624 ret = -ENOMEM;
625 goto ERR3;
626 }
627
628 device_wakeup_enable(hcd->self.controller);
629 platform_set_drvdata(pdev, hcd);
630
631 device_create_file(&pdev->dev, &dev_attr_ed_test);
632 device_create_file(&pdev->dev, &dev_attr_phy_threshold);
633 device_create_file(&pdev->dev, &dev_attr_phy_range);
634
635 #ifndef USB_SYNC_SUSPEND
636 device_enable_async_suspend(&pdev->dev);
637 #endif
638
639 #if IS_ENABLED(CONFIG_PM)
640 if (!sunxi_ehci->wakeup_suspend)
641 INIT_WORK(&sunxi_ehci->resume_work, sunxi_ehci_resume_work);
642 #endif
643
644 sunxi_ehci->probe = 1;
645
646 return 0;
647
648 ERR3:
649 sunxi_stop_ehci(sunxi_ehci);
650 usb_put_hcd(hcd);
651
652 ERR2:
653 sunxi_ehci->hcd = NULL;
654 g_sunxi_ehci[sunxi_ehci->usbc_no] = NULL;
655
656 ERR1:
657
658 return ret;
659 }
660
sunxi_rmmod_ehci(struct platform_device * pdev)661 int sunxi_rmmod_ehci(struct platform_device *pdev)
662 {
663
664 struct usb_hcd *hcd = NULL;
665 struct sunxi_hci_hcd *sunxi_ehci = NULL;
666 unsigned long time_left;
667
668 if (pdev == NULL) {
669 DMSG_PANIC("ERR: Argment is invalid\n");
670 return -1;
671 }
672
673 hcd = platform_get_drvdata(pdev);
674 if (hcd == NULL) {
675 DMSG_PANIC("ERR: hcd is null\n");
676 return -1;
677 }
678
679 sunxi_ehci = pdev->dev.platform_data;
680 if (sunxi_ehci == NULL) {
681 DMSG_PANIC("ERR: sunxi_ehci is null\n");
682 return -1;
683 }
684
685 if (atomic_read(&ehci_in_standby)) {
686 reinit_completion(&sunxi_ehci->standby_complete);
687 DMSG_INFO("INFO: sunxi_ehci disable, waiting until standby finish\n");
688 time_left = wait_for_completion_timeout(&sunxi_ehci->standby_complete,
689 msecs_to_jiffies(STANDBY_TIMEOUT));
690 if (time_left)
691 DMSG_INFO("INFO: sunxi_ehci disable time_left = %lu\n", time_left);
692 else
693 DMSG_PANIC("ERR: sunxi_ehci waiting standby failed, go on disable\n");
694
695 }
696
697 sunxi_ehci->probe = 0;
698
699 #ifndef USB_SYNC_SUSPEND
700 device_disable_async_suspend(&pdev->dev);
701 #endif
702
703 DMSG_INFO("[%s%d]: remove, pdev->name: %s, sunxi_ehci: 0x%px\n",
704 ehci_name, sunxi_ehci->usbc_no, pdev->name, sunxi_ehci);
705
706 device_remove_file(&pdev->dev, &dev_attr_ed_test);
707 device_remove_file(&pdev->dev, &dev_attr_phy_threshold);
708 device_remove_file(&pdev->dev, &dev_attr_phy_range);
709
710 device_wakeup_disable(hcd->self.controller);
711
712 usb_remove_hcd(hcd);
713
714 #if IS_ENABLED(CONFIG_PM)
715 if (!sunxi_ehci->wakeup_suspend)
716 if (!IS_ERR_OR_NULL(&sunxi_ehci->resume_work))
717 cancel_work_sync(&sunxi_ehci->resume_work);
718 #endif
719
720 sunxi_stop_ehci(sunxi_ehci);
721
722 usb_put_hcd(hcd);
723
724 if (sunxi_ehci->supply)
725 regulator_put(sunxi_ehci->supply);
726
727 sunxi_ehci->hcd = NULL;
728
729 return 0;
730 }
731
sunxi_ehci_hcd_probe(struct platform_device * pdev)732 static int sunxi_ehci_hcd_probe(struct platform_device *pdev)
733 {
734 int ret = 0;
735 #if defined(CONFIG_ARCH_SUN50IW10)
736 int val = 0;
737 #endif
738 struct sunxi_hci_hcd *sunxi_ehci = NULL;
739 if (pdev == NULL) {
740 DMSG_PANIC("ERR: %s, Argment is invalid\n", __func__);
741 return -1;
742 }
743
744 /* if usb is disabled, can not probe */
745 if (usb_disabled()) {
746 DMSG_PANIC("ERR: usb hcd is disabled\n");
747 return -ENODEV;
748 }
749
750 ret = init_sunxi_hci(pdev, SUNXI_USB_EHCI);
751 if (ret != 0) {
752 dev_err(&pdev->dev, "init_sunxi_hci is fail\n");
753 return -1;
754 }
755
756 sunxi_insmod_ehci(pdev);
757
758 sunxi_ehci = pdev->dev.platform_data;
759 if (sunxi_ehci == NULL) {
760 DMSG_PANIC("ERR: %s, sunxi_ehci is null\n", __func__);
761 return -1;
762 }
763
764 if (sunxi_ehci->usbc_no == HCI0_USBC_NO) {
765 ret = register_pm_notifier(&sunxi_ehci_pm_nb);
766 if (ret) {
767 DMSG_PANIC("ERR: %s, can not register suspend notifier\n", __func__);
768 return -1;
769 }
770 }
771
772 init_completion(&sunxi_ehci->standby_complete);
773
774 /* keep common circuit configuration when usb0 enable only*/
775 #if defined(CONFIG_ARCH_SUN50IW10)
776 if (sunxi_ehci->usbc_no == HCI0_USBC_NO) {
777 val = readl(sunxi_ehci->usb_ccmu_config + 0x0A8C);
778 val |= (SUNXI_CCMU_USBEHCI1_GATING_OFFSET
779 | SUNXI_CCMU_USBEHCI1_RST_OFFSET);
780 writel(val, sunxi_ehci->usb_ccmu_config + 0x0A8C);
781
782 val = readl(sunxi_ehci->usb_ccmu_config + 0x0A74);
783 val |= (SUNXI_CCMU_SCLK_GATING_USBPHY1_OFFSET
784 | SUNXI_CCMU_USBPHY1_RST_OFFSET
785 | SUNXI_CCMU_SCLK_GATING_OHCI1_OFFSET);
786 writel(val, sunxi_ehci->usb_ccmu_config + 0x0A74);
787
788 /*phy reg, offset:0x10 bit3 set 0, enable siddq*/
789 val = USBC_Readl(sunxi_ehci->usb_common_phy_config
790 + SUNXI_HCI_PHY_CTRL);
791 val &= ~(0x1 << SUNXI_HCI_PHY_CTRL_SIDDQ);
792 USBC_Writel(val, sunxi_ehci->usb_common_phy_config
793 + SUNXI_HCI_PHY_CTRL);
794 }
795 #endif
796
797 if (ehci_enable[sunxi_ehci->usbc_no]) {
798 device_create_file(&pdev->dev, &dev_attr_ehci_enable);
799 ehci_enable[sunxi_ehci->usbc_no] = 0;
800 }
801
802 return 0;
803 }
804
sunxi_ehci_hcd_remove(struct platform_device * pdev)805 static int sunxi_ehci_hcd_remove(struct platform_device *pdev)
806 {
807 struct sunxi_hci_hcd *sunxi_ehci = NULL;
808 int ret = 0;
809 #if defined(CONFIG_ARCH_SUN50IW10)
810 int val = 0;
811 #endif
812
813 if (pdev == NULL) {
814 DMSG_PANIC("ERR: %s, Argment is invalid\n", __func__);
815 return -1;
816 }
817
818 sunxi_ehci = pdev->dev.platform_data;
819 if (sunxi_ehci == NULL) {
820 DMSG_PANIC("ERR: %s, sunxi_ehci is null\n", __func__);
821 return -1;
822 }
823
824 if (ehci_enable[sunxi_ehci->usbc_no] == 0) {
825 device_remove_file(&pdev->dev, &dev_attr_ehci_enable);
826 ehci_enable[sunxi_ehci->usbc_no] = 1;
827 }
828
829 /* reset common circuit configuration*/
830 #if defined(CONFIG_ARCH_SUN50IW10)
831 if (sunxi_ehci->usbc_no == HCI0_USBC_NO) {
832 val = readl(sunxi_ehci->usb_ccmu_config + 0x0A8C);
833 val &= ~(SUNXI_CCMU_USBEHCI1_GATING_OFFSET
834 | SUNXI_CCMU_USBEHCI1_RST_OFFSET);
835 writel(val, sunxi_ehci->usb_ccmu_config + 0x0A8C);
836
837 val = readl(sunxi_ehci->usb_ccmu_config + 0x0A74);
838 val &= ~(SUNXI_CCMU_SCLK_GATING_USBPHY1_OFFSET
839 | SUNXI_CCMU_USBPHY1_RST_OFFSET
840 | SUNXI_CCMU_SCLK_GATING_OHCI1_OFFSET);
841 writel(val, sunxi_ehci->usb_ccmu_config + 0x0A74);
842
843 /*phy reg, offset:0x10 bit3 set 0, enable siddq*/
844 val = USBC_Readl(sunxi_ehci->usb_common_phy_config
845 + SUNXI_HCI_PHY_CTRL);
846 val |= (0x1 << SUNXI_HCI_PHY_CTRL_SIDDQ);
847 USBC_Writel(val, sunxi_ehci->usb_common_phy_config
848 + SUNXI_HCI_PHY_CTRL);
849 }
850 #endif
851
852 if (sunxi_ehci->usbc_no == HCI0_USBC_NO)
853 unregister_pm_notifier(&sunxi_ehci_pm_nb);
854
855 if (sunxi_ehci->probe == 1) {
856 ret = sunxi_rmmod_ehci(pdev);
857 if (ret == 0)
858 exit_sunxi_hci(sunxi_ehci);
859
860 return ret;
861 } else
862 return 0;
863
864 }
865
sunxi_ehci_hcd_shutdown(struct platform_device * pdev)866 static void sunxi_ehci_hcd_shutdown(struct platform_device *pdev)
867 {
868 struct sunxi_hci_hcd *sunxi_ehci = NULL;
869
870 if (pdev == NULL) {
871 DMSG_PANIC("ERR: %s, Argment is invalid\n", __func__);
872 return;
873 }
874
875 sunxi_ehci = pdev->dev.platform_data;
876 if (sunxi_ehci == NULL) {
877 DMSG_PANIC("ERR: %s, is null\n", __func__);
878 return;
879 }
880
881 if (sunxi_ehci->probe == 0) {
882 DMSG_INFO("%s, %s is disable, need not shutdown\n",
883 __func__, sunxi_ehci->hci_name);
884 return;
885 }
886
887 DMSG_INFO("[%s]: ehci shutdown start\n", sunxi_ehci->hci_name);
888 usb_hcd_platform_shutdown(pdev);
889
890 /**
891 * disable usb otg INTUSBE, to solve usb0 device mode
892 * catch audio udev on reboot system is fail.
893 */
894 if (sunxi_ehci->usbc_no == 0) {
895 if (sunxi_ehci->otg_vbase) {
896 writel(0, (sunxi_ehci->otg_vbase
897 + SUNXI_USBC_REG_INTUSBE));
898 }
899 }
900 sunxi_hcd_board_set_vbus(sunxi_ehci, 0);
901 DMSG_INFO("[%s]: ehci shutdown end\n", sunxi_ehci->hci_name);
902 }
903
904 #if IS_ENABLED(CONFIG_PM)
905
sunxi_ehci_hcd_suspend(struct device * dev)906 static int sunxi_ehci_hcd_suspend(struct device *dev)
907 {
908 struct sunxi_hci_hcd *sunxi_ehci = NULL;
909 struct usb_hcd *hcd = NULL;
910 struct ehci_hcd *ehci = NULL;
911 int val = 0;
912
913 if (dev == NULL) {
914 DMSG_PANIC("ERR: %s, Argment is invalid\n", __func__);
915 return 0;
916 }
917
918 hcd = dev_get_drvdata(dev);
919 if (hcd == NULL) {
920 DMSG_PANIC("ERR: hcd is null\n");
921 return 0;
922 }
923
924 sunxi_ehci = dev->platform_data;
925 if (sunxi_ehci == NULL) {
926 DMSG_PANIC("ERR: sunxi_ehci is null\n");
927 return 0;
928 }
929
930 if (sunxi_ehci->no_suspend) {
931 DMSG_INFO("[%s]:ehci is being enable, stop system suspend\n",
932 sunxi_ehci->hci_name);
933 return -1;
934 }
935
936 if (sunxi_ehci->probe == 0) {
937 DMSG_INFO("[%s]: is disable, can not suspend\n",
938 sunxi_ehci->hci_name);
939 return 0;
940 }
941
942 ehci = hcd_to_ehci(hcd);
943 if (ehci == NULL) {
944 DMSG_PANIC("ERR: ehci is null\n");
945 return 0;
946 }
947
948 if (sunxi_ehci->wakeup_suspend == USB_STANDBY) {
949 DMSG_INFO("[%s] usb suspend\n", sunxi_ehci->hci_name);
950 disable_irq(sunxi_ehci->irq_no);
951 /*phy reg, offset:0x18 bit0 bit1 bit2, set 1*/
952 val = ehci_readl(ehci, &ehci->regs->intr_enable);
953 val |= (0x7 << 0);
954 ehci_writel(ehci, val, &ehci->regs->intr_enable);
955
956 #if IS_ENABLED(SUNXI_USB_STANDBY_LOW_POW_MODE)
957 /*phy reg, offset:0x10 bit4 bit5, set 0*/
958 val = ehci_readl(ehci, &ehci->regs->command);
959 val &= ~(0x30);
960 ehci_writel(ehci, val, &ehci->regs->command);
961 /*enable standby irq*/
962 #endif
963 enter_usb_standby(sunxi_ehci);
964
965 } else {
966 DMSG_INFO("[%s]super suspend\n", sunxi_ehci->hci_name);
967
968 ehci_suspend(hcd, device_may_wakeup(dev));
969 cancel_work_sync(&sunxi_ehci->resume_work);
970 sunxi_stop_ehci(sunxi_ehci);
971 }
972
973 return 0;
974 }
975
sunxi_ehci_resume_work(struct work_struct * work)976 static void sunxi_ehci_resume_work(struct work_struct *work)
977 {
978 struct sunxi_hci_hcd *sunxi_ehci = NULL;
979
980 sunxi_ehci = container_of(work, struct sunxi_hci_hcd, resume_work);
981
982 sunxi_hcd_board_set_vbus(sunxi_ehci, 1);
983 }
984
sunxi_ehci_hcd_resume(struct device * dev)985 static int sunxi_ehci_hcd_resume(struct device *dev)
986 {
987 struct sunxi_hci_hcd *sunxi_ehci = NULL;
988 struct usb_hcd *hcd = NULL;
989 struct ehci_hcd *ehci = NULL;
990 int __maybe_unused val = 0;
991
992 if (dev == NULL) {
993 DMSG_PANIC("ERR: Argment is invalid\n");
994 return 0;
995 }
996
997 hcd = dev_get_drvdata(dev);
998 if (hcd == NULL) {
999 DMSG_PANIC("ERR: hcd is null\n");
1000 return 0;
1001 }
1002
1003 sunxi_ehci = dev->platform_data;
1004 if (sunxi_ehci == NULL) {
1005 DMSG_PANIC("ERR: sunxi_ehci is null\n");
1006 return 0;
1007 }
1008
1009 if (sunxi_ehci->probe == 0) {
1010 DMSG_INFO("[%s]: is disable, can not resume\n",
1011 sunxi_ehci->hci_name);
1012 return 0;
1013 }
1014
1015 ehci = hcd_to_ehci(hcd);
1016 if (ehci == NULL) {
1017 DMSG_PANIC("ERR: ehci is null\n");
1018 return 0;
1019 }
1020
1021 if (sunxi_ehci->wakeup_suspend == USB_STANDBY) {
1022 DMSG_INFO("[%s]usb resume\n", sunxi_ehci->hci_name);
1023
1024 exit_usb_standby(sunxi_ehci);
1025 #if IS_ENABLED(SUNXI_USB_STANDBY_LOW_POW_MODE)
1026 val = ehci_readl(ehci, &ehci->regs->command);
1027 val |= 0x30;
1028 ehci_writel(ehci, val, &ehci->regs->command);
1029
1030 #endif
1031 enable_irq(sunxi_ehci->irq_no);
1032 } else {
1033 DMSG_INFO("[%s]super resume\n", sunxi_ehci->hci_name);
1034
1035 open_ehci_clock(sunxi_ehci);
1036 sunxi_hcd_board_set_passby(sunxi_ehci, 1);
1037 ehci_resume(hcd, false);
1038
1039 #if defined(CONFIG_ARCH_SUN50IW10)
1040 if (sunxi_ehci->usbc_no == HCI0_USBC_NO) {
1041 /*phy reg, offset:0x10 bit3 set 0, enable siddq*/
1042 val = USBC_Readl(sunxi_ehci->usb_common_phy_config
1043 + SUNXI_HCI_PHY_CTRL);
1044 val &= ~(0x1 << SUNXI_HCI_PHY_CTRL_SIDDQ);
1045 USBC_Writel(val, sunxi_ehci->usb_common_phy_config
1046 + SUNXI_HCI_PHY_CTRL);
1047 }
1048 #endif
1049
1050 schedule_work(&sunxi_ehci->resume_work);
1051 }
1052
1053 return 0;
1054 }
1055
1056 static const struct dev_pm_ops aw_ehci_pmops = {
1057 .suspend = sunxi_ehci_hcd_suspend,
1058 .resume = sunxi_ehci_hcd_resume,
1059 };
1060
1061 #define SUNXI_EHCI_PMOPS (&aw_ehci_pmops)
1062
1063 #else
1064
1065 #define SUNXI_EHCI_PMOPS NULL
1066
1067 #endif
1068
1069
1070 static const struct of_device_id sunxi_ehci_match[] = {
1071 {.compatible = SUNXI_EHCI0_OF_MATCH, },
1072 {.compatible = SUNXI_EHCI1_OF_MATCH, },
1073 {.compatible = SUNXI_EHCI2_OF_MATCH, },
1074 {.compatible = SUNXI_EHCI3_OF_MATCH, },
1075 {},
1076 };
1077 MODULE_DEVICE_TABLE(of, sunxi_ehci_match);
1078
1079 static struct platform_driver sunxi_ehci_hcd_driver = {
1080 .probe = sunxi_ehci_hcd_probe,
1081 .remove = sunxi_ehci_hcd_remove,
1082 .shutdown = sunxi_ehci_hcd_shutdown,
1083 .driver = {
1084 .name = ehci_name,
1085 .pm = SUNXI_EHCI_PMOPS,
1086 .of_match_table = sunxi_ehci_match,
1087 }
1088 };
1089
sunxi_usb_disable_ehci(__u32 usbc_no)1090 int sunxi_usb_disable_ehci(__u32 usbc_no)
1091 {
1092 struct sunxi_hci_hcd *sunxi_ehci = NULL;
1093
1094 sunxi_ehci = g_sunxi_ehci[usbc_no];
1095 if (sunxi_ehci == NULL) {
1096 DMSG_PANIC("ERR: sunxi_ehci is null\n");
1097 return -1;
1098 }
1099
1100 if (sunxi_ehci->probe == 0) {
1101 DMSG_PANIC("ERR: sunxi_ehci is disable, can not disable again\n");
1102 return -1;
1103 }
1104
1105 sunxi_ehci->probe = 0;
1106
1107 DMSG_INFO("[%s]: sunxi_usb_disable_ehci\n", sunxi_ehci->hci_name);
1108
1109 sunxi_rmmod_ehci(sunxi_ehci->pdev);
1110
1111 return 0;
1112 }
1113 EXPORT_SYMBOL(sunxi_usb_disable_ehci);
1114
sunxi_usb_enable_ehci(__u32 usbc_no)1115 int sunxi_usb_enable_ehci(__u32 usbc_no)
1116 {
1117 struct sunxi_hci_hcd *sunxi_ehci = NULL;
1118 #if defined(CONFIG_ARCH_SUN50IW10)
1119 int val;
1120 #endif
1121
1122 sunxi_ehci = g_sunxi_ehci[usbc_no];
1123 if (sunxi_ehci == NULL) {
1124 DMSG_PANIC("ERR: sunxi_ehci is null\n");
1125 return -1;
1126 }
1127
1128 if (sunxi_ehci->probe == 1) {
1129 DMSG_PANIC("ERR: sunxi_ehci is already enable, can not enable again\n");
1130 return -1;
1131 }
1132
1133 sunxi_ehci->no_suspend = 1;
1134
1135 DMSG_INFO("[%s]: sunxi_usb_enable_ehci\n", sunxi_ehci->hci_name);
1136
1137 #if defined(CONFIG_ARCH_SUN50IW10)
1138 if (sunxi_ehci->usbc_no == HCI0_USBC_NO) {
1139 /*phy reg, offset:0x10 bit3 set 0, enable siddq*/
1140 val = USBC_Readl(sunxi_ehci->usb_common_phy_config
1141 + SUNXI_HCI_PHY_CTRL);
1142 val &= ~(0x1 << SUNXI_HCI_PHY_CTRL_SIDDQ);
1143 USBC_Writel(val, sunxi_ehci->usb_common_phy_config
1144 + SUNXI_HCI_PHY_CTRL);
1145 }
1146 #endif
1147
1148 sunxi_insmod_ehci(sunxi_ehci->pdev);
1149
1150 sunxi_ehci->no_suspend = 0;
1151
1152 return 0;
1153 }
1154 EXPORT_SYMBOL(sunxi_usb_enable_ehci);
1155
sunxi_ehci_hcd_init(void)1156 static int __init sunxi_ehci_hcd_init(void)
1157 {
1158 if (usb_disabled()) {
1159 DMSG_ERR(KERN_ERR "%s nousb\n", ehci_name);
1160 return -ENODEV;
1161 }
1162
1163 DMSG_INFO(KERN_INFO "%s: " DRIVER_DESC "\n", ehci_name);
1164 ehci_init_driver(&sunxi_ehci_hc_driver, NULL);
1165 return platform_driver_register(&sunxi_ehci_hcd_driver);
1166 }
1167 module_init(sunxi_ehci_hcd_init);
1168
sunxi_ehci_hcd_cleanup(void)1169 static void __exit sunxi_ehci_hcd_cleanup(void)
1170 {
1171 platform_driver_unregister(&sunxi_ehci_hcd_driver);
1172 }
1173 module_exit(sunxi_ehci_hcd_cleanup);
1174
1175 MODULE_DESCRIPTION(DRIVER_DESC);
1176 MODULE_LICENSE("GPL v2");
1177 MODULE_ALIAS("platform:" SUNXI_EHCI_NAME);
1178 MODULE_AUTHOR("javen");
1179 MODULE_VERSION("1.0.9");
1180