diff options
Diffstat (limited to 'drivers/usb/host/xhci.c')
-rw-r--r-- | drivers/usb/host/xhci.c | 57 |
1 files changed, 49 insertions, 8 deletions
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 40e0a0c221b8..27345cd04da0 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. |
@@ -116,6 +143,7 @@ int xhci_reset(struct xhci_hcd *xhci) | |||
116 | { | 143 | { |
117 | u32 command; | 144 | u32 command; |
118 | u32 state; | 145 | u32 state; |
146 | int ret; | ||
119 | 147 | ||
120 | state = xhci_readl(xhci, &xhci->op_regs->status); | 148 | state = xhci_readl(xhci, &xhci->op_regs->status); |
121 | if ((state & STS_HALT) == 0) { | 149 | if ((state & STS_HALT) == 0) { |
@@ -130,7 +158,17 @@ int xhci_reset(struct xhci_hcd *xhci) | |||
130 | /* XXX: Why does EHCI set this here? Shouldn't other code do this? */ | 158 | /* XXX: Why does EHCI set this here? Shouldn't other code do this? */ |
131 | xhci_to_hcd(xhci)->state = HC_STATE_HALT; | 159 | xhci_to_hcd(xhci)->state = HC_STATE_HALT; |
132 | 160 | ||
133 | return handshake(xhci, &xhci->op_regs->command, CMD_RESET, 0, 250 * 1000); | 161 | ret = handshake(xhci, &xhci->op_regs->command, |
162 | CMD_RESET, 0, 250 * 1000); | ||
163 | if (ret) | ||
164 | return ret; | ||
165 | |||
166 | xhci_dbg(xhci, "Wait for controller to be ready for doorbell rings\n"); | ||
167 | /* | ||
168 | * xHCI cannot write to any doorbells or operational registers other | ||
169 | * than status until the "Controller Not Ready" flag is cleared. | ||
170 | */ | ||
171 | return handshake(xhci, &xhci->op_regs->status, STS_CNR, 0, 250 * 1000); | ||
134 | } | 172 | } |
135 | 173 | ||
136 | 174 | ||
@@ -448,17 +486,20 @@ int xhci_run(struct usb_hcd *hcd) | |||
448 | 486 | ||
449 | if (NUM_TEST_NOOPS > 0) | 487 | if (NUM_TEST_NOOPS > 0) |
450 | doorbell = xhci_setup_one_noop(xhci); | 488 | doorbell = xhci_setup_one_noop(xhci); |
489 | if (xhci->quirks & XHCI_NEC_HOST) | ||
490 | xhci_queue_vendor_command(xhci, 0, 0, 0, | ||
491 | TRB_TYPE(TRB_NEC_GET_FW)); | ||
492 | |||
493 | if (xhci_start(xhci)) { | ||
494 | xhci_halt(xhci); | ||
495 | return -ENODEV; | ||
496 | } | ||
451 | 497 | ||
452 | temp = xhci_readl(xhci, &xhci->op_regs->command); | ||
453 | temp |= (CMD_RUN); | ||
454 | xhci_dbg(xhci, "// Turn on HC, cmd = 0x%x.\n", | ||
455 | temp); | ||
456 | xhci_writel(xhci, temp, &xhci->op_regs->command); | ||
457 | /* Flush PCI posted writes */ | ||
458 | temp = xhci_readl(xhci, &xhci->op_regs->command); | ||
459 | xhci_dbg(xhci, "// @%p = 0x%x\n", &xhci->op_regs->command, temp); | 498 | xhci_dbg(xhci, "// @%p = 0x%x\n", &xhci->op_regs->command, temp); |
460 | if (doorbell) | 499 | if (doorbell) |
461 | (*doorbell)(xhci); | 500 | (*doorbell)(xhci); |
501 | if (xhci->quirks & XHCI_NEC_HOST) | ||
502 | xhci_ring_cmd_db(xhci); | ||
462 | 503 | ||
463 | xhci_dbg(xhci, "Finished xhci_run\n"); | 504 | xhci_dbg(xhci, "Finished xhci_run\n"); |
464 | return 0; | 505 | return 0; |