summaryrefslogtreecommitdiff
path: root/drivers/usb
diff options
context:
space:
mode:
authormake shi <b15407@freescale.com>2012-05-31 10:24:10 +0800
committerJason Liu <r64343@freescale.com>2012-07-20 13:38:20 +0800
commitbf14d133e9cdb8101858d6623f5aa590a6cfe97c (patch)
tree332a03bded549c235e8de1d352f75408bcf26974 /drivers/usb
parentddc66f3dc1b2960b8572241538fd61037d948fd8 (diff)
ENGR00210686 USB:fix unplug&plug device during suspend without wakeup enabled
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>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/core/hub.c9
-rwxr-xr-xdrivers/usb/host/ehci-arc.c15
2 files changed, 19 insertions, 5 deletions
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 45540466d8fb..f293c69c15a6 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -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
diff --git a/drivers/usb/host/ehci-arc.c b/drivers/usb/host/ehci-arc.c
index 3fddb2f27245..08324a62292e 100755
--- a/drivers/usb/host/ehci-arc.c
+++ b/drivers/usb/host/ehci-arc.c
@@ -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;