]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
ENGR00210686 USB:fix unplug&plug device during suspend without wakeup enabled
authormake shi <b15407@freescale.com>
Thu, 31 May 2012 02:24:10 +0000 (10:24 +0800)
committerLothar Waßmann <LW@KARO-electronics.de>
Fri, 24 May 2013 06:34:45 +0000 (08:34 +0200)
For High speed device ,we need clear BM_USBPHY_CTRL_ENHOSTDISCONDETECT
after suspend.For Low and full speed device, we should power on and power
off the USB port to make sure USB internal state machine work well.

Add a config to enable/disable this code,the code is enabled by default.

Signed-off-by: make shi <b15407@freescale.com>
drivers/usb/core/hub.c
drivers/usb/host/ehci-arc.c

index 45540466d8fb951e76fbe7f39e5291b3395a3c4e..f293c69c15a66c37c78e05b5285e0d8d49398b55 100644 (file)
@@ -3209,11 +3209,10 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
                                pdata->init(NULL);
                }
                if ((port1 == 1) && (hdev->level == 0)) {
-                       if (!(portstatus & USB_PORT_STAT_CONNECTION)) {
-                               /* Must clear HOSTDISCONDETECT when disconnect*/
-                               if (pdata->platform_set_disconnect_det)
-                                       pdata->platform_set_disconnect_det(pdata, 0);
-                       }
+                       /* Must clear HOSTDISCONDETECT when port connect change happen*/
+                       if (pdata->platform_set_disconnect_det)
+                               pdata->platform_set_disconnect_det(pdata, 0);
+
                }
        }
 #endif
index 3fddb2f27245bc20ddaf2ff755e661af9ee88099..08324a62292e48efc8d2debd2dbf5a5c9f8d3f7c 100755 (executable)
@@ -771,6 +771,21 @@ static int ehci_fsl_drv_resume(struct platform_device *pdev)
 
                        usb_host_set_wakeup(hcd->self.controller, true);
 
+#ifndef NO_FIX_DISCONNECT_ISSUE
+                       /*Unplug&plug device during suspend without remote wakeup enabled
+                       For Low and full speed device, we should power on and power off
+                       the USB port to make sure USB internal state machine work well.
+                       */
+                       tmp = ehci_readl(ehci, &ehci->regs->port_status[0]);
+                       if ((tmp & PORT_CONNECT) && !(tmp & PORT_SUSPEND) &&
+                               ((tmp & (0x3<<26)) != (0x2<<26))) {
+                                       printk(KERN_DEBUG "%s will do power off and power on port.\n", pdata->name);
+                                       ehci_writel(ehci, tmp & ~(PORT_RWC_BITS | PORT_POWER),
+                                               &ehci->regs->port_status[0]);
+                                       ehci_writel(ehci, tmp | PORT_POWER,
+                                               &ehci->regs->port_status[0]);
+                       }
+#endif
                        fsl_usb_clk_gate(hcd->self.controller->platform_data, false);
                }
                return 0;