diff options
| -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); |
