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. " |