diff options
Diffstat (limited to 'drivers/usb/host/xhci-hcd.c')
-rw-r--r-- | drivers/usb/host/xhci-hcd.c | 152 |
1 files changed, 151 insertions, 1 deletions
diff --git a/drivers/usb/host/xhci-hcd.c b/drivers/usb/host/xhci-hcd.c index 011f47810665..a99c119e9fd9 100644 --- a/drivers/usb/host/xhci-hcd.c +++ b/drivers/usb/host/xhci-hcd.c | |||
@@ -218,6 +218,120 @@ int xhci_init(struct usb_hcd *hcd) | |||
218 | } | 218 | } |
219 | 219 | ||
220 | /* | 220 | /* |
221 | * Called in interrupt context when there might be work | ||
222 | * queued on the event ring | ||
223 | * | ||
224 | * xhci->lock must be held by caller. | ||
225 | */ | ||
226 | static void xhci_work(struct xhci_hcd *xhci) | ||
227 | { | ||
228 | u32 temp; | ||
229 | |||
230 | /* | ||
231 | * Clear the op reg interrupt status first, | ||
232 | * so we can receive interrupts from other MSI-X interrupters. | ||
233 | * Write 1 to clear the interrupt status. | ||
234 | */ | ||
235 | temp = xhci_readl(xhci, &xhci->op_regs->status); | ||
236 | temp |= STS_EINT; | ||
237 | xhci_writel(xhci, temp, &xhci->op_regs->status); | ||
238 | /* FIXME when MSI-X is supported and there are multiple vectors */ | ||
239 | /* Clear the MSI-X event interrupt status */ | ||
240 | |||
241 | /* Acknowledge the interrupt */ | ||
242 | temp = xhci_readl(xhci, &xhci->ir_set->irq_pending); | ||
243 | temp |= 0x3; | ||
244 | xhci_writel(xhci, temp, &xhci->ir_set->irq_pending); | ||
245 | /* Flush posted writes */ | ||
246 | xhci_readl(xhci, &xhci->ir_set->irq_pending); | ||
247 | |||
248 | /* FIXME this should be a delayed service routine that clears the EHB */ | ||
249 | handle_event(xhci); | ||
250 | |||
251 | /* Clear the event handler busy flag; the event ring should be empty. */ | ||
252 | temp = xhci_readl(xhci, &xhci->ir_set->erst_dequeue[0]); | ||
253 | xhci_writel(xhci, temp & ~ERST_EHB, &xhci->ir_set->erst_dequeue[0]); | ||
254 | /* Flush posted writes -- FIXME is this necessary? */ | ||
255 | xhci_readl(xhci, &xhci->ir_set->irq_pending); | ||
256 | } | ||
257 | |||
258 | /*-------------------------------------------------------------------------*/ | ||
259 | |||
260 | /* | ||
261 | * xHCI spec says we can get an interrupt, and if the HC has an error condition, | ||
262 | * we might get bad data out of the event ring. Section 4.10.2.7 has a list of | ||
263 | * indicators of an event TRB error, but we check the status *first* to be safe. | ||
264 | */ | ||
265 | irqreturn_t xhci_irq(struct usb_hcd *hcd) | ||
266 | { | ||
267 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); | ||
268 | u32 temp, temp2; | ||
269 | |||
270 | spin_lock(&xhci->lock); | ||
271 | /* Check if the xHC generated the interrupt, or the irq is shared */ | ||
272 | temp = xhci_readl(xhci, &xhci->op_regs->status); | ||
273 | temp2 = xhci_readl(xhci, &xhci->ir_set->irq_pending); | ||
274 | if (!(temp & STS_EINT) && !ER_IRQ_PENDING(temp2)) { | ||
275 | spin_unlock(&xhci->lock); | ||
276 | return IRQ_NONE; | ||
277 | } | ||
278 | |||
279 | temp = xhci_readl(xhci, &xhci->op_regs->status); | ||
280 | if (temp & STS_FATAL) { | ||
281 | xhci_warn(xhci, "WARNING: Host System Error\n"); | ||
282 | xhci_halt(xhci); | ||
283 | xhci_to_hcd(xhci)->state = HC_STATE_HALT; | ||
284 | return -ESHUTDOWN; | ||
285 | } | ||
286 | |||
287 | xhci_work(xhci); | ||
288 | spin_unlock(&xhci->lock); | ||
289 | |||
290 | return IRQ_HANDLED; | ||
291 | } | ||
292 | |||
293 | #ifdef CONFIG_USB_XHCI_HCD_DEBUGGING | ||
294 | void event_ring_work(unsigned long arg) | ||
295 | { | ||
296 | unsigned long flags; | ||
297 | int temp; | ||
298 | struct xhci_hcd *xhci = (struct xhci_hcd *) arg; | ||
299 | int i, j; | ||
300 | |||
301 | xhci_dbg(xhci, "Poll event ring: %lu\n", jiffies); | ||
302 | |||
303 | spin_lock_irqsave(&xhci->lock, flags); | ||
304 | temp = xhci_readl(xhci, &xhci->op_regs->status); | ||
305 | xhci_dbg(xhci, "op reg status = 0x%x\n", temp); | ||
306 | temp = xhci_readl(xhci, &xhci->ir_set->irq_pending); | ||
307 | xhci_dbg(xhci, "ir_set 0 pending = 0x%x\n", temp); | ||
308 | xhci_dbg(xhci, "No-op commands handled = %d\n", xhci->noops_handled); | ||
309 | xhci_dbg(xhci, "HC error bitmask = 0x%x\n", xhci->error_bitmask); | ||
310 | xhci->error_bitmask = 0; | ||
311 | xhci_dbg(xhci, "Event ring:\n"); | ||
312 | xhci_debug_segment(xhci, xhci->event_ring->deq_seg); | ||
313 | xhci_dbg_ring_ptrs(xhci, xhci->event_ring); | ||
314 | temp = xhci_readl(xhci, &xhci->ir_set->erst_dequeue[0]); | ||
315 | temp &= ERST_PTR_MASK; | ||
316 | xhci_dbg(xhci, "ERST deq = 0x%x\n", temp); | ||
317 | xhci_dbg(xhci, "Command ring:\n"); | ||
318 | xhci_debug_segment(xhci, xhci->cmd_ring->deq_seg); | ||
319 | xhci_dbg_ring_ptrs(xhci, xhci->cmd_ring); | ||
320 | xhci_dbg_cmd_ptrs(xhci); | ||
321 | |||
322 | if (xhci->noops_submitted != NUM_TEST_NOOPS) | ||
323 | if (setup_one_noop(xhci)) | ||
324 | ring_cmd_db(xhci); | ||
325 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
326 | |||
327 | if (!xhci->zombie) | ||
328 | mod_timer(&xhci->event_ring_timer, jiffies + POLL_TIMEOUT * HZ); | ||
329 | else | ||
330 | xhci_dbg(xhci, "Quit polling the event ring.\n"); | ||
331 | } | ||
332 | #endif | ||
333 | |||
334 | /* | ||
221 | * Start the HC after it was halted. | 335 | * Start the HC after it was halted. |
222 | * | 336 | * |
223 | * This function is called by the USB core when the HC driver is added. | 337 | * This function is called by the USB core when the HC driver is added. |
@@ -233,8 +347,9 @@ int xhci_run(struct usb_hcd *hcd) | |||
233 | { | 347 | { |
234 | u32 temp; | 348 | u32 temp; |
235 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); | 349 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); |
236 | xhci_dbg(xhci, "xhci_run\n"); | 350 | void (*doorbell)(struct xhci_hcd *) = NULL; |
237 | 351 | ||
352 | xhci_dbg(xhci, "xhci_run\n"); | ||
238 | #if 0 /* FIXME: MSI not setup yet */ | 353 | #if 0 /* FIXME: MSI not setup yet */ |
239 | /* Do this at the very last minute */ | 354 | /* Do this at the very last minute */ |
240 | ret = xhci_setup_msix(xhci); | 355 | ret = xhci_setup_msix(xhci); |
@@ -243,6 +358,17 @@ int xhci_run(struct usb_hcd *hcd) | |||
243 | 358 | ||
244 | return -ENOSYS; | 359 | return -ENOSYS; |
245 | #endif | 360 | #endif |
361 | #ifdef CONFIG_USB_XHCI_HCD_DEBUGGING | ||
362 | init_timer(&xhci->event_ring_timer); | ||
363 | xhci->event_ring_timer.data = (unsigned long) xhci; | ||
364 | xhci->event_ring_timer.function = event_ring_work; | ||
365 | /* Poll the event ring */ | ||
366 | xhci->event_ring_timer.expires = jiffies + POLL_TIMEOUT * HZ; | ||
367 | xhci->zombie = 0; | ||
368 | xhci_dbg(xhci, "Setting event ring polling timer\n"); | ||
369 | add_timer(&xhci->event_ring_timer); | ||
370 | #endif | ||
371 | |||
246 | xhci_dbg(xhci, "// Set the interrupt modulation register\n"); | 372 | xhci_dbg(xhci, "// Set the interrupt modulation register\n"); |
247 | temp = xhci_readl(xhci, &xhci->ir_set->irq_control); | 373 | temp = xhci_readl(xhci, &xhci->ir_set->irq_control); |
248 | temp &= 0xffff; | 374 | temp &= 0xffff; |
@@ -266,10 +392,24 @@ int xhci_run(struct usb_hcd *hcd) | |||
266 | &xhci->ir_set->irq_pending); | 392 | &xhci->ir_set->irq_pending); |
267 | xhci_print_ir_set(xhci, xhci->ir_set, 0); | 393 | xhci_print_ir_set(xhci, xhci->ir_set, 0); |
268 | 394 | ||
395 | if (NUM_TEST_NOOPS > 0) | ||
396 | doorbell = setup_one_noop(xhci); | ||
397 | |||
269 | xhci_dbg(xhci, "Command ring memory map follows:\n"); | 398 | xhci_dbg(xhci, "Command ring memory map follows:\n"); |
270 | xhci_debug_ring(xhci, xhci->cmd_ring); | 399 | xhci_debug_ring(xhci, xhci->cmd_ring); |
400 | xhci_dbg_ring_ptrs(xhci, xhci->cmd_ring); | ||
401 | xhci_dbg_cmd_ptrs(xhci); | ||
402 | |||
271 | xhci_dbg(xhci, "ERST memory map follows:\n"); | 403 | xhci_dbg(xhci, "ERST memory map follows:\n"); |
272 | xhci_dbg_erst(xhci, &xhci->erst); | 404 | xhci_dbg_erst(xhci, &xhci->erst); |
405 | xhci_dbg(xhci, "Event ring:\n"); | ||
406 | xhci_debug_ring(xhci, xhci->event_ring); | ||
407 | xhci_dbg_ring_ptrs(xhci, xhci->event_ring); | ||
408 | temp = xhci_readl(xhci, &xhci->ir_set->erst_dequeue[1]); | ||
409 | xhci_dbg(xhci, "ERST deq upper = 0x%x\n", temp); | ||
410 | temp = xhci_readl(xhci, &xhci->ir_set->erst_dequeue[0]); | ||
411 | temp &= ERST_PTR_MASK; | ||
412 | xhci_dbg(xhci, "ERST deq = 0x%x\n", temp); | ||
273 | 413 | ||
274 | temp = xhci_readl(xhci, &xhci->op_regs->command); | 414 | temp = xhci_readl(xhci, &xhci->op_regs->command); |
275 | temp |= (CMD_RUN); | 415 | temp |= (CMD_RUN); |
@@ -280,6 +420,8 @@ int xhci_run(struct usb_hcd *hcd) | |||
280 | temp = xhci_readl(xhci, &xhci->op_regs->command); | 420 | temp = xhci_readl(xhci, &xhci->op_regs->command); |
281 | xhci_dbg(xhci, "// @%x = 0x%x\n", | 421 | xhci_dbg(xhci, "// @%x = 0x%x\n", |
282 | (unsigned int) &xhci->op_regs->command, temp); | 422 | (unsigned int) &xhci->op_regs->command, temp); |
423 | if (doorbell) | ||
424 | (*doorbell)(xhci); | ||
283 | 425 | ||
284 | xhci_dbg(xhci, "Finished xhci_run\n"); | 426 | xhci_dbg(xhci, "Finished xhci_run\n"); |
285 | return 0; | 427 | return 0; |
@@ -309,6 +451,12 @@ void xhci_stop(struct usb_hcd *hcd) | |||
309 | #if 0 /* No MSI yet */ | 451 | #if 0 /* No MSI yet */ |
310 | xhci_cleanup_msix(xhci); | 452 | xhci_cleanup_msix(xhci); |
311 | #endif | 453 | #endif |
454 | #ifdef CONFIG_USB_XHCI_HCD_DEBUGGING | ||
455 | /* Tell the event ring poll function not to reschedule */ | ||
456 | xhci->zombie = 1; | ||
457 | del_timer_sync(&xhci->event_ring_timer); | ||
458 | #endif | ||
459 | |||
312 | xhci_dbg(xhci, "// Disabling event ring interrupts\n"); | 460 | xhci_dbg(xhci, "// Disabling event ring interrupts\n"); |
313 | temp = xhci_readl(xhci, &xhci->op_regs->status); | 461 | temp = xhci_readl(xhci, &xhci->op_regs->status); |
314 | xhci_writel(xhci, temp & ~STS_EINT, &xhci->op_regs->status); | 462 | xhci_writel(xhci, temp & ~STS_EINT, &xhci->op_regs->status); |
@@ -346,6 +494,8 @@ void xhci_shutdown(struct usb_hcd *hcd) | |||
346 | xhci_readl(xhci, &xhci->op_regs->status)); | 494 | xhci_readl(xhci, &xhci->op_regs->status)); |
347 | } | 495 | } |
348 | 496 | ||
497 | /*-------------------------------------------------------------------------*/ | ||
498 | |||
349 | int xhci_get_frame(struct usb_hcd *hcd) | 499 | int xhci_get_frame(struct usb_hcd *hcd) |
350 | { | 500 | { |
351 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); | 501 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); |