aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/xhci.c
diff options
context:
space:
mode:
authorSarah Sharp <sarah.a.sharp@linux.intel.com>2010-05-24 16:25:21 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2010-06-04 16:16:19 -0400
commited07453fd356025cc25272629e982f5e4607632c (patch)
treec3c08950b4f98c10e67c7b317b1233e755f53f6c /drivers/usb/host/xhci.c
parent2d62f3eea98354d61f90d6b115eecf9be5f4bdfe (diff)
USB: xhci: Wait for host to start running.
When the run bit is set in the xHCI command register, it may take a few microseconds for the host to start running. We cannot ring any doorbells until the host is actually running, so wait until the status register says the host is running. Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com> Reported-by: Shinya Saito <shinya.saito.sx@renesas.com> Cc: stable <stable@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/host/xhci.c')
-rw-r--r--drivers/usb/host/xhci.c39
1 files changed, 32 insertions, 7 deletions
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 79ccfe5f8ad0..8a49c6716b69 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -106,6 +106,33 @@ int xhci_halt(struct xhci_hcd *xhci)
106} 106}
107 107
108/* 108/*
109 * Set the run bit and wait for the host to be running.
110 */
111int xhci_start(struct xhci_hcd *xhci)
112{
113 u32 temp;
114 int ret;
115
116 temp = xhci_readl(xhci, &xhci->op_regs->command);
117 temp |= (CMD_RUN);
118 xhci_dbg(xhci, "// Turn on HC, cmd = 0x%x.\n",
119 temp);
120 xhci_writel(xhci, temp, &xhci->op_regs->command);
121
122 /*
123 * Wait for the HCHalted Status bit to be 0 to indicate the host is
124 * running.
125 */
126 ret = handshake(xhci, &xhci->op_regs->status,
127 STS_HALT, 0, XHCI_MAX_HALT_USEC);
128 if (ret == -ETIMEDOUT)
129 xhci_err(xhci, "Host took too long to start, "
130 "waited %u microseconds.\n",
131 XHCI_MAX_HALT_USEC);
132 return ret;
133}
134
135/*
109 * Reset a halted HC, and set the internal HC state to HC_STATE_HALT. 136 * Reset a halted HC, and set the internal HC state to HC_STATE_HALT.
110 * 137 *
111 * This resets pipelines, timers, counters, state machines, etc. 138 * This resets pipelines, timers, counters, state machines, etc.
@@ -460,13 +487,11 @@ int xhci_run(struct usb_hcd *hcd)
460 if (NUM_TEST_NOOPS > 0) 487 if (NUM_TEST_NOOPS > 0)
461 doorbell = xhci_setup_one_noop(xhci); 488 doorbell = xhci_setup_one_noop(xhci);
462 489
463 temp = xhci_readl(xhci, &xhci->op_regs->command); 490 if (xhci_start(xhci)) {
464 temp |= (CMD_RUN); 491 xhci_halt(xhci);
465 xhci_dbg(xhci, "// Turn on HC, cmd = 0x%x.\n", 492 return -ENODEV;
466 temp); 493 }
467 xhci_writel(xhci, temp, &xhci->op_regs->command); 494
468 /* Flush PCI posted writes */
469 temp = xhci_readl(xhci, &xhci->op_regs->command);
470 xhci_dbg(xhci, "// @%p = 0x%x\n", &xhci->op_regs->command, temp); 495 xhci_dbg(xhci, "// @%p = 0x%x\n", &xhci->op_regs->command, temp);
471 if (doorbell) 496 if (doorbell)
472 (*doorbell)(xhci); 497 (*doorbell)(xhci);