diff options
Diffstat (limited to 'drivers/usb/host/xhci.c')
-rw-r--r-- | drivers/usb/host/xhci.c | 39 |
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 | */ | ||
111 | int 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); |