diff options
| -rw-r--r-- | drivers/usb/host/xhci-ring.c | 18 |
1 files changed, 10 insertions, 8 deletions
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index f479f73711ac..6860e9f097bb 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c | |||
| @@ -2014,7 +2014,7 @@ static void xhci_handle_event(struct xhci_hcd *xhci) | |||
| 2014 | irqreturn_t xhci_irq(struct usb_hcd *hcd) | 2014 | irqreturn_t xhci_irq(struct usb_hcd *hcd) |
| 2015 | { | 2015 | { |
| 2016 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); | 2016 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); |
| 2017 | u32 status, irq_pending; | 2017 | u32 status; |
| 2018 | union xhci_trb *trb; | 2018 | union xhci_trb *trb; |
| 2019 | u64 temp_64; | 2019 | u64 temp_64; |
| 2020 | union xhci_trb *event_ring_deq; | 2020 | union xhci_trb *event_ring_deq; |
| @@ -2024,17 +2024,15 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd) | |||
| 2024 | trb = xhci->event_ring->dequeue; | 2024 | trb = xhci->event_ring->dequeue; |
| 2025 | /* Check if the xHC generated the interrupt, or the irq is shared */ | 2025 | /* Check if the xHC generated the interrupt, or the irq is shared */ |
| 2026 | status = xhci_readl(xhci, &xhci->op_regs->status); | 2026 | status = xhci_readl(xhci, &xhci->op_regs->status); |
| 2027 | irq_pending = xhci_readl(xhci, &xhci->ir_set->irq_pending); | 2027 | if (status == 0xffffffff) |
| 2028 | if (status == 0xffffffff && irq_pending == 0xffffffff) | ||
| 2029 | goto hw_died; | 2028 | goto hw_died; |
| 2030 | 2029 | ||
| 2031 | if (!(status & STS_EINT) && !ER_IRQ_PENDING(irq_pending)) { | 2030 | if (!(status & STS_EINT)) { |
| 2032 | spin_unlock(&xhci->lock); | 2031 | spin_unlock(&xhci->lock); |
| 2033 | xhci_warn(xhci, "Spurious interrupt.\n"); | 2032 | xhci_warn(xhci, "Spurious interrupt.\n"); |
| 2034 | return IRQ_NONE; | 2033 | return IRQ_NONE; |
| 2035 | } | 2034 | } |
| 2036 | xhci_dbg(xhci, "op reg status = %08x\n", status); | 2035 | xhci_dbg(xhci, "op reg status = %08x\n", status); |
| 2037 | xhci_dbg(xhci, "ir set irq_pending = %08x\n", irq_pending); | ||
| 2038 | xhci_dbg(xhci, "Event ring dequeue ptr:\n"); | 2036 | xhci_dbg(xhci, "Event ring dequeue ptr:\n"); |
| 2039 | xhci_dbg(xhci, "@%llx %08x %08x %08x %08x\n", | 2037 | xhci_dbg(xhci, "@%llx %08x %08x %08x %08x\n", |
| 2040 | (unsigned long long) | 2038 | (unsigned long long) |
| @@ -2063,9 +2061,13 @@ hw_died: | |||
| 2063 | /* FIXME when MSI-X is supported and there are multiple vectors */ | 2061 | /* FIXME when MSI-X is supported and there are multiple vectors */ |
| 2064 | /* Clear the MSI-X event interrupt status */ | 2062 | /* Clear the MSI-X event interrupt status */ |
| 2065 | 2063 | ||
| 2066 | /* Acknowledge the interrupt */ | 2064 | if (hcd->irq != -1) { |
| 2067 | irq_pending |= 0x3; | 2065 | u32 irq_pending; |
| 2068 | xhci_writel(xhci, irq_pending, &xhci->ir_set->irq_pending); | 2066 | /* Acknowledge the PCI interrupt */ |
| 2067 | irq_pending = xhci_readl(xhci, &xhci->ir_set->irq_pending); | ||
| 2068 | irq_pending |= 0x3; | ||
| 2069 | xhci_writel(xhci, irq_pending, &xhci->ir_set->irq_pending); | ||
| 2070 | } | ||
| 2069 | 2071 | ||
| 2070 | if (xhci->xhc_state & XHCI_STATE_DYING) { | 2072 | if (xhci->xhc_state & XHCI_STATE_DYING) { |
| 2071 | xhci_dbg(xhci, "xHCI dying, ignoring interrupt. " | 2073 | xhci_dbg(xhci, "xHCI dying, ignoring interrupt. " |
