1 #if 0
2 /*
3  * drivers/usb/host/ohci_sunxi.c
4  * (C) Copyright 2010-2015
5  * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
6  * yangnaitian, 2011-5-24, create this file
7  * javen, 2011-6-26, add suspend and resume
8  * javen, 2011-7-18, move clock and power operations out from driver
9  *
10  * OHCI Driver
11  *
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License as
14  * published by the Free Software Foundation; either version 2 of
15  * the License, or (at your option) any later version.
16  *
17  */
18 
19 #include <linux/platform_device.h>
20 #include <linux/signal.h>
21 #include <linux/time.h>
22 #include <linux/timer.h>
23 #include <linux/clk.h>
24 #include <linux/notifier.h>
25 #include <linux/suspend.h>
26 #include "sunxi_hci.h"
27 
28 #if defined(CONFIG_ARCH_SUN50IW10)
29 #include "../../clk/sunxi/clk-sun50iw10.h"
30 #endif
31 
32 #define   SUNXI_OHCI_NAME   "sunxi-ohci"
33 static const char ohci_name[] = SUNXI_OHCI_NAME;
34 
35 #if IS_ENABLED(CONFIG_USB_SUNXI_OHCI0)
36 #define  SUNXI_OHCI0_OF_MATCH   "allwinner,sunxi-ohci0"
37 #else
38 #define  SUNXI_OHCI0_OF_MATCH   "null"
39 #endif
40 
41 #if IS_ENABLED(CONFIG_USB_SUNXI_OHCI1)
42 #define  SUNXI_OHCI1_OF_MATCH   "allwinner,sunxi-ohci1"
43 #else
44 #define  SUNXI_OHCI1_OF_MATCH   "null"
45 #endif
46 
47 #if IS_ENABLED(CONFIG_USB_SUNXI_OHCI2)
48 #define  SUNXI_OHCI2_OF_MATCH   "allwinner,sunxi-ohci2"
49 #else
50 #define  SUNXI_OHCI2_OF_MATCH   "null"
51 #endif
52 
53 #if IS_ENABLED(CONFIG_USB_SUNXI_OHCI3)
54 #define  SUNXI_OHCI3_OF_MATCH   "allwinner,sunxi-ohci3"
55 #else
56 #define  SUNXI_OHCI3_OF_MATCH   "null"
57 #endif
58 
59 static struct sunxi_hci_hcd *g_sunxi_ohci[4];
60 static u32 ohci_first_probe[4] = {1, 1, 1, 1};
61 static u32 ohci_enable[4] = {1, 1, 1, 1};
62 static atomic_t ohci_in_standby;
63 
64 #ifdef CONFIG_PM
65 static void sunxi_ohci_resume_work(struct work_struct *work);
66 #endif
67 
68 int sunxi_usb_disable_ohci(__u32 usbc_no);
69 int sunxi_usb_enable_ohci(__u32 usbc_no);
70 
71 static ssize_t ohci_enable_show(struct device *dev,
72         struct device_attribute *attr, char *buf)
73 {
74     struct sunxi_hci_hcd *sunxi_ohci = NULL;
75 
76     if (dev == NULL) {
77         DMSG_PANIC("ERR: Argment is invalid\n");
78         return 0;
79     }
80 
81     sunxi_ohci = dev->platform_data;
82     if (sunxi_ohci == NULL) {
83         DMSG_PANIC("ERR: sw_ohci is null\n");
84         return 0;
85     }
86 
87     return sprintf(buf, "ohci:%d,probe:%u\n",
88             sunxi_ohci->usbc_no, sunxi_ohci->probe);
89 }
90 
91 static ssize_t ohci_enable_store(struct device *dev,
92         struct device_attribute *attr,
93         const char *buf, size_t count)
94 {
95     struct sunxi_hci_hcd *sunxi_ohci = NULL;
96     int value = 0;
97     int err;
98 
99     if (dev == NULL) {
100         DMSG_PANIC("ERR: Argment is invalid\n");
101         return 0;
102     }
103 
104     sunxi_ohci = dev->platform_data;
105     if (sunxi_ohci == NULL) {
106         DMSG_PANIC("ERR: sw_ohci is null\n");
107         return 0;
108     }
109 
110     ohci_first_probe[sunxi_ohci->usbc_no] = 0;
111 
112     err = kstrtoint(buf, 10, &value);
113     if (err != 0)
114         return -EINVAL;
115     if (value == 1) {
116         ohci_enable[sunxi_ohci->usbc_no] = 0;
117         sunxi_usb_enable_ohci(sunxi_ohci->usbc_no);
118 
119         if (sunxi_ohci->usbc_no == HCI0_USBC_NO)
120             sunxi_set_host_vbus(sunxi_ohci, 1);
121 
122     } else if (value == 0) {
123         ohci_enable[sunxi_ohci->usbc_no] = 1;
124         sunxi_usb_disable_ohci(sunxi_ohci->usbc_no);
125         ohci_enable[sunxi_ohci->usbc_no] = 0;
126     } else {
127         DMSG_INFO("unknown value (%d)\n", value);
128     }
129 
130     return count;
131 }
132 
133 static DEVICE_ATTR(ohci_enable, 0644, ohci_enable_show, ohci_enable_store);
134 
135 static int open_ohci_clock(struct sunxi_hci_hcd *sunxi_ohci)
136 {
137     return sunxi_ohci->open_clock(sunxi_ohci, 1);
138 }
139 
140 static int close_ohci_clock(struct sunxi_hci_hcd *sunxi_ohci)
141 {
142     return sunxi_ohci->close_clock(sunxi_ohci, 1);
143 }
144 
145 static void sunxi_ohci_set_vbus(struct sunxi_hci_hcd *sunxi_ohci, int is_on)
146 {
147     sunxi_ohci->set_power(sunxi_ohci, is_on);
148 }
149 
150 static void sunxi_ohci_set_passby(struct sunxi_hci_hcd *sunxi_ohci, int is_on)
151 {
152     sunxi_ohci->usb_passby(sunxi_ohci, is_on);
153 }
154 
155 static void sunxi_start_ohci(struct sunxi_hci_hcd *sunxi_ohci)
156 {
157     open_ohci_clock(sunxi_ohci);
158     sunxi_ohci_set_passby(sunxi_ohci, 1);
159     sunxi_ohci_set_vbus(sunxi_ohci, 1);
160 }
161 
162 static void sunxi_stop_ohci(struct sunxi_hci_hcd *sunxi_ohci)
163 {
164     sunxi_ohci_set_vbus(sunxi_ohci, 0);
165     sunxi_ohci_set_passby(sunxi_ohci, 0);
166     close_ohci_clock(sunxi_ohci);
167 }
168 
169 static int sunxi_ohci_start(struct usb_hcd *hcd)
170 {
171     struct ohci_hcd *ohci = hcd_to_ohci(hcd);
172     int ret;
173 
174     ret = ohci_init(ohci);
175     if (ret < 0)
176         return ret;
177 
178     ret = ohci_run(ohci);
179     if (ret < 0) {
180         DMSG_PANIC("can't start %s", hcd->self.bus_name);
181         ohci_stop(hcd);
182         return ret;
183     }
184 
185     return 0;
186 }
187 
188 static int sunxi_ohci_pm_notify(struct notifier_block *nb,
189                 unsigned long mode, void *_unused)
190 {
191     switch (mode) {
192     case PM_HIBERNATION_PREPARE:
193     case PM_RESTORE_PREPARE:
194     case PM_SUSPEND_PREPARE:
195         atomic_set(&ohci_in_standby, 1);
196         break;
197     case PM_POST_HIBERNATION:
198     case PM_POST_RESTORE:
199     case PM_POST_SUSPEND:
200         atomic_set(&ohci_in_standby, 0);
201         sunxi_hci_standby_completion(SUNXI_USB_OHCI);
202         break;
203     default:
204         break;
205     }
206 
207     return 0;
208 }
209 
210 static struct notifier_block sunxi_ohci_pm_nb = {
211     .notifier_call = sunxi_ohci_pm_notify,
212 };
213 
214 static const struct hc_driver sunxi_ohci_hc_driver = {
215     .description    = hcd_name,
216     .product_desc   = "SW USB2.0 'Open' Host Controller (OHCI) Driver",
217     .hcd_priv_size  = sizeof(struct ohci_hcd),
218 
219     /*
220      * generic hardware linkage
221      */
222     .irq            = ohci_irq,
223     .flags          = HCD_USB11 | HCD_MEMORY,
224 
225     /*
226      * basic lifecycle operations
227      */
228     .start          = sunxi_ohci_start,
229     .stop           = ohci_stop,
230     .shutdown       = ohci_shutdown,
231 
232     /*
233      * managing i/o requests and associated device resources
234      */
235     .urb_enqueue        = ohci_urb_enqueue,
236     .urb_dequeue        = ohci_urb_dequeue,
237     .endpoint_disable   = ohci_endpoint_disable,
238 
239     /*
240      * scheduling support
241      */
242     .get_frame_number   = ohci_get_frame,
243 
244     /*
245      * root hub support
246      */
247     .hub_status_data    = ohci_hub_status_data,
248     .hub_control        = ohci_hub_control,
249 
250 #ifdef  CONFIG_PM
251     .bus_suspend        = ohci_bus_suspend,
252     .bus_resume     = ohci_bus_resume,
253 #endif
254     .start_port_reset   = ohci_start_port_reset,
255 };
256 
257 static int sunxi_insmod_ohci(struct platform_device *pdev)
258 {
259     int ret;
260     struct usb_hcd *hcd = NULL;
261     struct sunxi_hci_hcd *sunxi_ohci = NULL;
262 #if defined(CONFIG_SUNXI_REGULATOR_DT)
263     struct device *dev = NULL;
264 #endif
265 
266     if (pdev == NULL) {
267         DMSG_PANIC("ERR: Argment is invaild\n");
268         return -1;
269     }
270 
271     /* if usb is disabled, can not probe */
272     if (usb_disabled()) {
273         DMSG_PANIC("ERR: usb hcd is disabled\n");
274         return -ENODEV;
275     }
276 
277     sunxi_ohci = pdev->dev.platform_data;
278     if (!sunxi_ohci) {
279         DMSG_PANIC("ERR: sunxi_ohci is null\n");
280         ret = -ENOMEM;
281         goto ERR1;
282     }
283 
284     sunxi_ohci->pdev = pdev;
285     g_sunxi_ohci[sunxi_ohci->usbc_no] = sunxi_ohci;
286 
287     DMSG_INFO("[%s%d]: probe, pdev->name: %s, sunxi_ohci: 0x%p\n",
288         ohci_name, sunxi_ohci->usbc_no, pdev->name, sunxi_ohci);
289 
290     sunxi_ohci->ohci_base = sunxi_ohci->usb_vbase +
291                     SUNXI_USB_OHCI_BASE_OFFSET;
292 
293     sunxi_ohci->ohci_reg_length = SUNXI_USB_OHCI_LEN;
294 
295     /* not init ohci, when driver probe */
296     if (sunxi_ohci->usbc_no == HCI0_USBC_NO) {
297         if (sunxi_ohci->port_type != USB_PORT_TYPE_HOST) {
298             if (ohci_first_probe[sunxi_ohci->usbc_no]) {
299                 ohci_first_probe[sunxi_ohci->usbc_no] = 0;
300                 DMSG_INFO("[%s%d]: Not init ohci0\n",
301                       ohci_name, sunxi_ohci->usbc_no);
302                 return 0;
303             }
304         }
305     }
306 
307     /* creat a usb_hcd for the ohci controller */
308     hcd = usb_create_hcd(&sunxi_ohci_hc_driver, &pdev->dev, ohci_name);
309     if (!hcd) {
310         DMSG_PANIC("ERR: usb_ohci_create_hcd failed\n");
311         ret = -ENOMEM;
312         goto ERR2;
313     }
314 
315     hcd->rsrc_start = sunxi_ohci->usb_base_res->start;
316     hcd->rsrc_len   = SUNXI_USB_OHCI_LEN;
317     hcd->regs   = sunxi_ohci->ohci_base;
318     sunxi_ohci->hcd = hcd;
319 
320 #if defined(CONFIG_SUNXI_REGULATOR_DT)
321     dev = &pdev->dev;
322     sunxi_ohci->supply = regulator_get(dev, "drvvbus");
323 
324     if (IS_ERR(sunxi_ohci->supply)) {
325         DMSG_PANIC("%s()%d WARN: get supply failed\n", __func__, __LINE__);
326         sunxi_ohci->supply = NULL;
327     }
328 #endif
329 
330     /* ochi start to work */
331     sunxi_start_ohci(sunxi_ohci);
332 
333     ohci_hcd_init(hcd_to_ohci(hcd));
334 
335     ret = usb_add_hcd(hcd, sunxi_ohci->irq_no, IRQF_SHARED);
336     if (ret != 0) {
337         DMSG_PANIC("ERR: usb_add_hcd failed\n");
338         ret = -ENOMEM;
339         goto ERR3;
340     }
341 
342     device_wakeup_enable(hcd->self.controller);
343     platform_set_drvdata(pdev, hcd);
344 
345 #ifndef USB_SYNC_SUSPEND
346     device_enable_async_suspend(&pdev->dev);
347 #endif
348 
349 #ifdef CONFIG_PM
350     if (!sunxi_ohci->wakeup_suspend)
351         INIT_WORK(&sunxi_ohci->resume_work, sunxi_ohci_resume_work);
352 #endif
353 
354     sunxi_ohci->probe = 1;
355 
356     return 0;
357 
358 ERR3:
359     sunxi_stop_ohci(sunxi_ohci);
360     usb_put_hcd(hcd);
361 
362 ERR2:
363     sunxi_ohci->hcd = NULL;
364 
365 ERR1:
366     return ret;
367 }
368 
369 static int sunxi_rmmod_ohci(struct platform_device *pdev)
370 {
371     struct usb_hcd *hcd = NULL;
372     struct sunxi_hci_hcd *sunxi_ohci = NULL;
373     unsigned long time_left;
374 
375     if (pdev == NULL) {
376         DMSG_PANIC("ERR: Argment is invalid\n");
377         return -1;
378     }
379 
380     hcd = platform_get_drvdata(pdev);
381     if (hcd == NULL) {
382         DMSG_PANIC("ERR: hcd is null\n");
383         return -1;
384     }
385 
386     sunxi_ohci = pdev->dev.platform_data;
387     if (sunxi_ohci == NULL) {
388         DMSG_PANIC("ERR: sunxi_ohci is null\n");
389         return -1;
390     }
391 
392     if (atomic_read(&ohci_in_standby)) {
393         reinit_completion(&sunxi_ohci->standby_complete);
394         DMSG_INFO("INFO: sunxi_ohci disable, waiting until standby finish\n");
395         time_left = wait_for_completion_timeout(&sunxi_ohci->standby_complete,
396                         msecs_to_jiffies(STANDBY_TIMEOUT));
397         if (time_left)
398             DMSG_INFO("INFO: sunxi_ohci disable time_left = %lu\n", time_left);
399         else
400             DMSG_PANIC("ERR: sunxi_ohci waiting standby failed, go on disable\n");
401 
402     }
403 
404     sunxi_ohci->probe = 0;
405 
406     DMSG_INFO("[%s%d]: remove, pdev->name: %s, sunxi_ohci: 0x%p\n",
407         ohci_name, sunxi_ohci->usbc_no, pdev->name, sunxi_ohci);
408     usb_remove_hcd(hcd);
409 
410     sunxi_stop_ohci(sunxi_ohci);
411 
412     usb_put_hcd(hcd);
413 
414 #if defined(CONFIG_SUNXI_REGULATOR_DT)
415     if (sunxi_ohci->supply)
416         regulator_put(sunxi_ohci->supply);
417 #endif
418 
419     sunxi_ohci->hcd = NULL;
420 
421     return 0;
422 }
423 
424 static int sunxi_ohci_hcd_probe(struct platform_device *pdev)
425 {
426     int ret = 0;
427 #if defined(CONFIG_ARCH_SUN50IW10)
428     int val = 0;
429 #endif
430     struct sunxi_hci_hcd *sunxi_ohci = NULL;
431 
432     if (pdev == NULL) {
433         DMSG_PANIC("ERR: %s, Argment is invalid\n", __func__);
434         return -1;
435     }
436 
437     /* if usb is disabled, can not probe */
438     if (usb_disabled()) {
439         DMSG_PANIC("ERR: usb hcd is disabled\n");
440         return -ENODEV;
441     }
442 
443     ret = init_sunxi_hci(pdev, SUNXI_USB_OHCI);
444     if (ret != 0) {
445         dev_err(&pdev->dev, "init_sunxi_hci is fail\n");
446         return -1;
447     }
448 
449     sunxi_insmod_ohci(pdev);
450 
451     sunxi_ohci = pdev->dev.platform_data;
452     if (sunxi_ohci == NULL) {
453         DMSG_PANIC("ERR: %s, sunxi_ohci is null\n", __func__);
454         return -1;
455     }
456 
457     if (sunxi_ohci->usbc_no == HCI0_USBC_NO) {
458         ret = register_pm_notifier(&sunxi_ohci_pm_nb);
459         if (ret) {
460             DMSG_PANIC("ERR: %s, can not register suspend notifier\n", __func__);
461             return -1;
462         }
463     }
464 
465     init_completion(&sunxi_ohci->standby_complete);
466 
467 /* keep common circuit configuration when usb0 enable only*/
468 #if defined(CONFIG_ARCH_SUN50IW10)
469     if (sunxi_ohci->usbc_no == HCI0_USBC_NO) {
470         /*phy reg, offset:0x10 bit3 set 0, enable siddq*/
471         val = USBC_Readl(sunxi_ohci->usb_common_phy_config + SUNXI_HCI_PHY_CTRL);
472         val &= ~(0x1 << SUNXI_HCI_PHY_CTRL_SIDDQ);
473         USBC_Writel(val, sunxi_ohci->usb_common_phy_config + SUNXI_HCI_PHY_CTRL);
474     }
475 #endif
476 
477     if (ohci_enable[sunxi_ohci->usbc_no]) {
478         device_create_file(&pdev->dev, &dev_attr_ohci_enable);
479         ohci_enable[sunxi_ohci->usbc_no] = 0;
480     }
481 
482     return 0;
483 }
484 
485 static int sunxi_ohci_hcd_remove(struct platform_device *pdev)
486 {
487     struct sunxi_hci_hcd *sunxi_ohci = NULL;
488 
489     int ret = 0;
490 
491     if (pdev == NULL) {
492         DMSG_PANIC("ERR: %s, Argment is invalid\n", __func__);
493         return -1;
494     }
495 
496     sunxi_ohci = pdev->dev.platform_data;
497     if (sunxi_ohci == NULL) {
498         DMSG_PANIC("ERR: %s, sunxi_ohci is null\n", __func__);
499         return -1;
500     }
501 
502     if (ohci_enable[sunxi_ohci->usbc_no] == 0)
503         device_remove_file(&pdev->dev, &dev_attr_ohci_enable);
504 
505     if (sunxi_ohci->probe == 1) {
506         ret = sunxi_rmmod_ohci(pdev);
507         if (ret == 0)
508             exit_sunxi_hci(sunxi_ohci);
509 
510         if (sunxi_ohci->usbc_no == HCI0_USBC_NO)
511             unregister_pm_notifier(&sunxi_ohci_pm_nb);
512 
513         return ret;
514     } else
515         return 0;
516 }
517 
518 static void sunxi_ohci_hcd_shutdown(struct platform_device *pdev)
519 {
520     struct sunxi_hci_hcd *sunxi_ohci = NULL;
521 
522     sunxi_ohci = pdev->dev.platform_data;
523     if (sunxi_ohci == NULL) {
524         DMSG_PANIC("ERR: %s sunxi_ohci is null\n", __func__);
525         return;
526     }
527 
528     if (sunxi_ohci->probe == 0) {
529         DMSG_INFO("%s, %s is disable, need not shutdown\n",
530             __func__, sunxi_ohci->hci_name);
531         return;
532     }
533 
534     pr_debug("[%s]: ohci shutdown start\n", sunxi_ohci->hci_name);
535 
536     usb_hcd_platform_shutdown(pdev);
537 
538     /**
539      * disable usb otg INTUSBE, to solve usb0 device mode
540      * catch audio udev on reboot system is fail.
541      */
542     if (sunxi_ohci->usbc_no == 0)
543         if (sunxi_ohci->otg_vbase) {
544             writel(0, (sunxi_ohci->otg_vbase
545                         + SUNXI_USBC_REG_INTUSBE));
546         }
547 
548     pr_debug("[%s]: ohci shutdown end\n", sunxi_ohci->hci_name);
549 }
550 
551 #ifdef CONFIG_PM
552 
553 static int sunxi_ohci_hcd_suspend(struct device *dev)
554 {
555     struct sunxi_hci_hcd *sunxi_ohci  = NULL;
556     struct usb_hcd *hcd = NULL;
557     struct ohci_hcd *ohci   = NULL;
558     int val = 0;
559 
560     if (dev == NULL) {
561         DMSG_PANIC("ERR: Argment is invalid\n");
562         return 0;
563     }
564 
565     hcd = dev_get_drvdata(dev);
566     if (hcd == NULL) {
567         DMSG_PANIC("ERR: hcd is null\n");
568         return 0;
569     }
570 
571     sunxi_ohci = dev->platform_data;
572     if (sunxi_ohci == NULL) {
573         DMSG_PANIC("ERR: sunxi_ohci is null\n");
574         return 0;
575     }
576 
577     if (sunxi_ohci->no_suspend) {
578         DMSG_INFO("[%s]:ohci is being enable, stop system suspend\n",
579             sunxi_ohci->hci_name);
580         return -1;
581     }
582 
583     if (sunxi_ohci->probe == 0) {
584         DMSG_INFO("[%s]: is disable, can not suspend\n",
585             sunxi_ohci->hci_name);
586         return 0;
587     }
588 
589     ohci = hcd_to_ohci(hcd);
590     if (ohci == NULL) {
591         DMSG_PANIC("ERR: ohci is null\n");
592         return 0;
593     }
594 
595     if (sunxi_ohci->wakeup_suspend == USB_STANDBY) {
596         DMSG_INFO("[%s] usb suspend\n", sunxi_ohci->hci_name);
597         val = ohci_readl(ohci, &ohci->regs->control);
598         val |= OHCI_CTRL_RWE;
599         ohci_writel(ohci, val,  &ohci->regs->control);
600 
601         val = ohci_readl(ohci, &ohci->regs->intrenable);
602         val |= OHCI_INTR_RD;
603         val |= OHCI_INTR_MIE;
604         ohci_writel(ohci, val, &ohci->regs->intrenable);
605 
606 #ifdef SUNXI_USB_STANDBY_LOW_POW_MODE
607         val = ohci_readl(ohci, &ohci->regs->control);
608         val |= OHCI_USB_SUSPEND;
609         ohci_writel(ohci, val, &ohci->regs->control);
610 
611 #ifdef SUNXI_USB_STANDBY_NEW_MODE
612         /*phy reg, offset:0x0 bit2, set 1, enable RC16M CLK*/
613         sunxi_hci_set_rc_clk(sunxi_ohci, 1);
614 #endif
615         /*phy reg, offset:0x08 bit3, set 1, remote enable*/
616         sunxi_hci_set_wakeup_ctrl(sunxi_ohci, 1);
617         /*phy reg, offset:0x10 bit3 set 1, clean siddq*/
618         sunxi_hci_set_siddq(sunxi_ohci, 1);
619 #endif
620 
621 #if defined(CONFIG_ARCH_SUN50IW10)
622         /*phy reg, offset:0x0 bit31, set 1*/
623         val = USBC_Readl(sunxi_ohci->usb_vbase + SUNXI_USB_PMU_IRQ_ENABLE);
624         val |= (0x1 << 31);
625         USBC_Writel(val, sunxi_ohci->usb_vbase + SUNXI_USB_PMU_IRQ_ENABLE);
626 
627         /*phy reg, offset:0x0 bit3, set 1*/
628         val = USBC_Readl(sunxi_ohci->usb_vbase + SUNXI_USB_PMU_IRQ_ENABLE);
629         val |= (0x1 << 3);
630         USBC_Writel(val, sunxi_ohci->usb_vbase + SUNXI_USB_PMU_IRQ_ENABLE);
631 
632         /*prcm, offset:0x0 bit3, set 1*/
633         val = USBC_Readl(sunxi_ohci->prcm);
634         val |= (0x1 << 3);
635         USBC_Writel(val, sunxi_ohci->prcm);
636 #endif
637 
638         if (sunxi_ohci->clk_usbohci12m && sunxi_ohci->clk_losc)
639             clk_set_parent(sunxi_ohci->clk_usbohci12m,
640                     sunxi_ohci->clk_losc);
641     } else {
642         DMSG_INFO("[%s]super suspend\n", sunxi_ohci->hci_name);
643         atomic_add(1, &g_sunxi_usb_super_standby);
644 
645         /**
646          * Root hub was already suspended. Disable irq emission and
647          * mark HW unaccessible, bail out if RH has been resumed. Use
648          * the spinlock to properly synchronize with possible pending
649          * RH suspend or resume activity.
650          *
651          * This is still racy as hcd->state is manipulated outside of
652          * any locks =P But that will be a different fix.
653          */
654         ohci_suspend(hcd, device_may_wakeup(dev));
655 
656         sunxi_stop_ohci(sunxi_ohci);
657         sunxi_hci_set_siddq(sunxi_ohci, 1);
658 
659         cancel_work_sync(&sunxi_ohci->resume_work);
660     }
661 
662     return 0;
663 }
664 
665 static void sunxi_ohci_resume_work(struct work_struct *work)
666 {
667     struct sunxi_hci_hcd *sunxi_ohci = NULL;
668 
669     sunxi_ohci = container_of(work, struct sunxi_hci_hcd, resume_work);
670 
671     /* Waiting hci to resume. */
672     msleep(5000);
673 
674     sunxi_ohci_set_vbus(sunxi_ohci, 1);
675     atomic_sub(1, &g_sunxi_usb_super_standby);
676 }
677 
678 static int sunxi_ohci_hcd_resume(struct device *dev)
679 {
680     struct sunxi_hci_hcd *sunxi_ohci = NULL;
681     struct usb_hcd *hcd = NULL;
682     struct ohci_hcd *ohci   = NULL;
683 #ifdef SUNXI_USB_STANDBY_LOW_POW_MODE
684     int val = 0;
685 #endif
686 
687     if (dev == NULL) {
688         DMSG_PANIC("ERR: Argment is invalid\n");
689         return 0;
690     }
691 
692     hcd = dev_get_drvdata(dev);
693     if (hcd == NULL) {
694         DMSG_PANIC("ERR: hcd is null\n");
695         return 0;
696     }
697 
698     sunxi_ohci = dev->platform_data;
699     if (sunxi_ohci == NULL) {
700         DMSG_PANIC("ERR: sunxi_ohci is null\n");
701         return 0;
702     }
703 
704     if (sunxi_ohci->probe == 0) {
705         DMSG_INFO("[%s]: is disable, can not resume\n",
706             sunxi_ohci->hci_name);
707         return 0;
708     }
709 
710     ohci = hcd_to_ohci(hcd);
711     if (ohci == NULL) {
712         DMSG_PANIC("ERR: ohci is null\n");
713         return 0;
714     }
715 
716     if (sunxi_ohci->wakeup_suspend == USB_STANDBY) {
717         DMSG_INFO("[%s]usb resume\n", sunxi_ohci->hci_name);
718 
719         if (sunxi_ohci->clk_usbohci12m && sunxi_ohci->clk_hoscx2)
720             clk_set_parent(sunxi_ohci->clk_usbohci12m,
721                     sunxi_ohci->clk_hoscx2);
722 
723 #if defined(CONFIG_ARCH_SUN50IW10)
724         /*prcm, offset:0x0 bit3, set 0*/
725         val = USBC_Readl(sunxi_ohci->prcm);
726         val &= ~(0x1 << 3);
727         USBC_Writel(val, sunxi_ohci->prcm);
728 
729         /*phy reg, offset:0x0 bit3, set 0*/
730         val = USBC_Readl(sunxi_ohci->usb_vbase + SUNXI_USB_PMU_IRQ_ENABLE);
731         val &= ~(0x1 << 3);
732         USBC_Writel(val, sunxi_ohci->usb_vbase + SUNXI_USB_PMU_IRQ_ENABLE);
733 
734         /*phy reg, offset:0x0 bit31, set 0*/
735         val = USBC_Readl(sunxi_ohci->usb_vbase + SUNXI_USB_PMU_IRQ_ENABLE);
736         val &= ~(0x1 << 31);
737         USBC_Writel(val, sunxi_ohci->usb_vbase + SUNXI_USB_PMU_IRQ_ENABLE);
738 #endif
739 
740 #ifdef SUNXI_USB_STANDBY_LOW_POW_MODE
741         /*phy reg, offset:0x10 bit3 set 0, enable siddq*/
742         sunxi_hci_set_siddq(sunxi_ohci, 0);
743         /*phy reg, offset:0x08 bit3, set 0, remote disable*/
744         sunxi_hci_set_wakeup_ctrl(sunxi_ohci, 0);
745 
746 #ifdef SUNXI_USB_STANDBY_NEW_MODE
747         /*disable rc clk*/
748         /*phy reg, offset:0x0 bit2, set 0, disable rc clk*/
749         sunxi_hci_set_rc_clk(sunxi_ohci, 0);
750 #endif
751 
752         val = ohci_readl(ohci, &ohci->regs->control);
753         val &= ~(OHCI_USB_SUSPEND);
754         ohci_writel(ohci, val, &ohci->regs->control);
755 #endif
756     } else {
757         DMSG_INFO("[%s]super resume\n", sunxi_ohci->hci_name);
758         sunxi_hci_set_siddq(sunxi_ohci, 0);
759         open_ohci_clock(sunxi_ohci);
760         sunxi_ohci_set_passby(sunxi_ohci, 1);
761         set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
762         ohci_resume(hcd, false);
763 
764 #if defined(CONFIG_ARCH_SUN50IW10)
765         if (sunxi_ohci->usbc_no == HCI0_USBC_NO) {
766             /*phy reg, offset:0x10 bit3 set 0, enable siddq*/
767             val = USBC_Readl(sunxi_ohci->usb_common_phy_config + SUNXI_HCI_PHY_CTRL);
768             val &= ~(0x1 << SUNXI_HCI_PHY_CTRL_SIDDQ);
769             USBC_Writel(val, sunxi_ohci->usb_common_phy_config + SUNXI_HCI_PHY_CTRL);
770         }
771 #endif
772 
773         schedule_work(&sunxi_ohci->resume_work);
774     }
775 
776     return 0;
777 }
778 
779 static const struct dev_pm_ops sunxi_ohci_pmops = {
780     .suspend    = sunxi_ohci_hcd_suspend,
781     .resume     = sunxi_ohci_hcd_resume,
782 };
783 
784 #define SUNXI_OHCI_PMOPS (&sunxi_ohci_pmops)
785 
786 #else
787 
788 #define SUNXI_OHCI_PMOPS NULL
789 
790 #endif
791 
792 static const struct of_device_id sunxi_ohci_match[] = {
793     {.compatible = SUNXI_OHCI0_OF_MATCH, },
794     {.compatible = SUNXI_OHCI1_OF_MATCH, },
795     {.compatible = SUNXI_OHCI2_OF_MATCH, },
796     {.compatible = SUNXI_OHCI3_OF_MATCH, },
797     {},
798 };
799 MODULE_DEVICE_TABLE(of, sunxi_ohci_match);
800 
801 
802 static struct platform_driver sunxi_ohci_hcd_driver = {
803     .probe      = sunxi_ohci_hcd_probe,
804     .remove     = sunxi_ohci_hcd_remove,
805     .shutdown   = sunxi_ohci_hcd_shutdown,
806     .driver     = {
807         .name   = ohci_name,
808         .owner  = THIS_MODULE,
809         .pm = SUNXI_OHCI_PMOPS,
810         .of_match_table = sunxi_ohci_match,
811     },
812 };
813 
814 int sunxi_usb_disable_ohci(__u32 usbc_no)
815 {
816     struct sunxi_hci_hcd *sunxi_ohci = NULL;
817 
818     sunxi_ohci = g_sunxi_ohci[usbc_no];
819     if (sunxi_ohci == NULL) {
820         DMSG_PANIC("ERR: sunxi_ohci is null\n");
821         return -1;
822     }
823 
824     if (sunxi_ohci->probe == 0) {
825         DMSG_PANIC("ERR: sunxi_ohci is disable, can not disable again\n");
826         return -1;
827     }
828 
829     sunxi_ohci->probe = 0;
830 
831     DMSG_INFO("[%s]: sunxi_usb_disable_ohci\n", sunxi_ohci->hci_name);
832 
833     sunxi_rmmod_ohci(sunxi_ohci->pdev);
834 
835     return 0;
836 }
837 EXPORT_SYMBOL(sunxi_usb_disable_ohci);
838 
839 int sunxi_usb_enable_ohci(__u32 usbc_no)
840 {
841     struct sunxi_hci_hcd *sunxi_ohci = NULL;
842 #if defined(CONFIG_ARCH_SUN50IW10)
843     int val;
844 #endif
845 
846     sunxi_ohci = g_sunxi_ohci[usbc_no];
847     if (sunxi_ohci == NULL) {
848         DMSG_PANIC("ERR: sunxi_ohci is null\n");
849         return -1;
850     }
851 
852     if (sunxi_ohci->probe == 1) {
853         DMSG_PANIC("ERR: sunxi_ohci is already enable, can not enable again\n");
854         return -1;
855     }
856 
857     sunxi_ohci->no_suspend = 1;
858 
859     DMSG_INFO("[%s]: sunxi_usb_enable_ohci\n", sunxi_ohci->hci_name);
860 
861 #if defined(CONFIG_ARCH_SUN50IW10)
862         if (sunxi_ohci->usbc_no == HCI0_USBC_NO) {
863             /*phy reg, offset:0x10 bit3 set 0, enable siddq*/
864             val = USBC_Readl(sunxi_ohci->usb_common_phy_config + SUNXI_HCI_PHY_CTRL);
865             val &= ~(0x1 << SUNXI_HCI_PHY_CTRL_SIDDQ);
866             USBC_Writel(val, sunxi_ohci->usb_common_phy_config + SUNXI_HCI_PHY_CTRL);
867         }
868 #endif
869 
870     sunxi_insmod_ohci(sunxi_ohci->pdev);
871 
872     sunxi_ohci->no_suspend = 0;
873 
874     return 0;
875 }
876 EXPORT_SYMBOL(sunxi_usb_enable_ohci);
877 
878 #endif
879