aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/host/xhci-ring.c18
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)
2014irqreturn_t xhci_irq(struct usb_hcd *hcd) 2014irqreturn_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. "