aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/xhci.c
diff options
context:
space:
mode:
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);