aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/ehci-hub.c
diff options
context:
space:
mode:
authorPeter Chen <peter.chen@freescale.com>2012-10-18 00:24:43 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-10-24 17:40:50 -0400
commit6273f1810f95f4deeb2f0d6810f301726ad32308 (patch)
tree202135972f6010f17312103e05642bbbed3cda07 /drivers/usb/host/ehci-hub.c
parente8cebb9cde3716800219ea8473306d431e83154b (diff)
USB: EHCI: add condition for delay during the resume
Without this condition, all controllers will do this delay, and increase the resume time. Only enabled and unsuspended port needs this delay, but Some buggy hardware(like Synopsys usb controller) will clear suspend bit once they receive/send resume signal, so it takes resume bit as consideration. Tested it at Freescale i.mx6q Sabrelite board. Signed-off-by: Peter Chen <peter.chen@freescale.com> Acked-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/host/ehci-hub.c')
-rw-r--r--drivers/usb/host/ehci-hub.c23
1 files changed, 18 insertions, 5 deletions
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
index 914ce9370e70..a7ec827ca2ca 100644
--- a/drivers/usb/host/ehci-hub.c
+++ b/drivers/usb/host/ehci-hub.c
@@ -384,11 +384,24 @@ static int ehci_bus_resume (struct usb_hcd *hcd)
384 ehci_writel(ehci, ehci->command, &ehci->regs->command); 384 ehci_writel(ehci, ehci->command, &ehci->regs->command);
385 ehci->rh_state = EHCI_RH_RUNNING; 385 ehci->rh_state = EHCI_RH_RUNNING;
386 386
387 /* Some controller/firmware combinations need a delay during which 387 /*
388 * they set up the port statuses. See Bugzilla #8190. */ 388 * According to Bugzilla #8190, the port status for some controllers
389 spin_unlock_irq(&ehci->lock); 389 * will be wrong without a delay. At their wrong status, the port
390 msleep(8); 390 * is enabled, but not suspended neither resumed.
391 spin_lock_irq(&ehci->lock); 391 */
392 i = HCS_N_PORTS(ehci->hcs_params);
393 while (i--) {
394 temp = ehci_readl(ehci, &ehci->regs->port_status[i]);
395 if ((temp & PORT_PE) &&
396 !(temp & (PORT_SUSPEND | PORT_RESUME))) {
397 ehci_dbg(ehci, "Port status(0x%x) is wrong\n", temp);
398 spin_unlock_irq(&ehci->lock);
399 msleep(8);
400 spin_lock_irq(&ehci->lock);
401 break;
402 }
403 }
404
392 if (ehci->shutdown) 405 if (ehci->shutdown)
393 goto shutdown; 406 goto shutdown;
394 407