MLK-13638-6 usb: chipidea: add recovery from vbus is off during system suspend
authorPeter Chen <peter.chen@nxp.com>
Fri, 30 Dec 2016 02:23:42 +0000 (10:23 +0800)
committerNitin Garg <nitin.garg@nxp.com>
Mon, 19 Mar 2018 19:58:19 +0000 (14:58 -0500)
When the vbus is off during the suspend controller is powered off, if we
do not want to see disconnection from USB core, we need to make sure the
device pulls DP up before USB core resume runs. However, several devices
are slow to pull DP up when see vbus (maybe it needs vbus to power up
system), so we need to wait connection at platform code.

Signed-off-by: Peter Chen <peter.chen@nxp.com>
drivers/usb/chipidea/host.c

index 6832da0..afef075 100644 (file)
@@ -431,6 +431,12 @@ static void ci_hdrc_host_restore_from_power_lost(struct ci_hdrc *ci)
        struct ehci_hcd *ehci;
        unsigned long   flags;
        u32 tmp;
+       int step_ms;
+       /*
+        * If the vbus is off during system suspend, most of devices will pull
+        * DP up within 200ms when they see vbus, set 1000ms for safety.
+        */
+       int timeout_ms = 1000;
 
        if (!ci->hcd)
                return;
@@ -458,6 +464,15 @@ static void ci_hdrc_host_restore_from_power_lost(struct ci_hdrc *ci)
        tmp |= CMD_RUN;
        ehci_writel(ehci, tmp, &ehci->regs->command);
        spin_unlock_irqrestore(&ehci->lock, flags);
+
+       if (!(ci->pm_portsc & PORTSC_CCS))
+               return;
+
+       for (step_ms = 0; step_ms < timeout_ms; step_ms += 25) {
+               if (ehci_readl(ehci, &ehci->regs->port_status[0]) & PORTSC_CCS)
+                       break;
+               msleep(25);
+       }
 }
 
 static void ci_hdrc_host_suspend(struct ci_hdrc *ci)