Commit 27e0dd4d authored by Sarah Sharp's avatar Sarah Sharp Committed by Greg Kroah-Hartman

USB: xhci: Remove unnecessary reads of IRQ_PENDING register.

Remove a duplicate register read of the interrupt pending register from
xhci_irq().  Also, remove waiting on the posted write of that register.
The host will see it eventually.  It will probably read the register
itself before deciding whether to interrupt the system again, forcing the
posted write to complete.
Signed-off-by: default avatarSarah Sharp <sarah.a.sharp@linux.intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent bda53145
...@@ -2039,25 +2039,25 @@ void xhci_handle_event(struct xhci_hcd *xhci) ...@@ -2039,25 +2039,25 @@ void xhci_handle_event(struct xhci_hcd *xhci)
irqreturn_t xhci_irq(struct usb_hcd *hcd) irqreturn_t xhci_irq(struct usb_hcd *hcd)
{ {
struct xhci_hcd *xhci = hcd_to_xhci(hcd); struct xhci_hcd *xhci = hcd_to_xhci(hcd);
u32 temp, temp2; u32 status, irq_pending;
union xhci_trb *trb; union xhci_trb *trb;
u64 temp_64; u64 temp_64;
spin_lock(&xhci->lock); spin_lock(&xhci->lock);
trb = xhci->event_ring->dequeue; trb = xhci->event_ring->dequeue;
/* Check if the xHC generated the interrupt, or the irq is shared */ /* Check if the xHC generated the interrupt, or the irq is shared */
temp = xhci_readl(xhci, &xhci->op_regs->status); status = xhci_readl(xhci, &xhci->op_regs->status);
temp2 = xhci_readl(xhci, &xhci->ir_set->irq_pending); irq_pending = xhci_readl(xhci, &xhci->ir_set->irq_pending);
if (temp == 0xffffffff && temp2 == 0xffffffff) if (status == 0xffffffff && irq_pending == 0xffffffff)
goto hw_died; goto hw_died;
if (!(temp & STS_EINT) && !ER_IRQ_PENDING(temp2)) { if (!(status & STS_EINT) && !ER_IRQ_PENDING(irq_pending)) {
spin_unlock(&xhci->lock); spin_unlock(&xhci->lock);
xhci_warn(xhci, "Spurious interrupt.\n"); xhci_warn(xhci, "Spurious interrupt.\n");
return IRQ_NONE; return IRQ_NONE;
} }
xhci_dbg(xhci, "op reg status = %08x\n", temp); xhci_dbg(xhci, "op reg status = %08x\n", status);
xhci_dbg(xhci, "ir set irq_pending = %08x\n", temp2); xhci_dbg(xhci, "ir set irq_pending = %08x\n", irq_pending);
xhci_dbg(xhci, "Event ring dequeue ptr:\n"); xhci_dbg(xhci, "Event ring dequeue ptr:\n");
xhci_dbg(xhci, "@%llx %08x %08x %08x %08x\n", xhci_dbg(xhci, "@%llx %08x %08x %08x %08x\n",
(unsigned long long) (unsigned long long)
...@@ -2067,7 +2067,7 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd) ...@@ -2067,7 +2067,7 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd)
(unsigned int) trb->link.intr_target, (unsigned int) trb->link.intr_target,
(unsigned int) trb->link.control); (unsigned int) trb->link.control);
if (temp & STS_FATAL) { if (status & STS_FATAL) {
xhci_warn(xhci, "WARNING: Host System Error\n"); xhci_warn(xhci, "WARNING: Host System Error\n");
xhci_halt(xhci); xhci_halt(xhci);
hw_died: hw_died:
...@@ -2081,15 +2081,14 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd) ...@@ -2081,15 +2081,14 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd)
* so we can receive interrupts from other MSI-X interrupters. * so we can receive interrupts from other MSI-X interrupters.
* Write 1 to clear the interrupt status. * Write 1 to clear the interrupt status.
*/ */
temp |= STS_EINT; status |= STS_EINT;
xhci_writel(xhci, temp, &xhci->op_regs->status); xhci_writel(xhci, status, &xhci->op_regs->status);
/* FIXME when MSI-X is supported and there are multiple vectors */ /* FIXME when MSI-X is supported and there are multiple vectors */
/* Clear the MSI-X event interrupt status */ /* Clear the MSI-X event interrupt status */
/* Acknowledge the interrupt */ /* Acknowledge the interrupt */
temp = xhci_readl(xhci, &xhci->ir_set->irq_pending); irq_pending |= 0x3;
temp |= 0x3; xhci_writel(xhci, irq_pending, &xhci->ir_set->irq_pending);
xhci_writel(xhci, temp, &xhci->ir_set->irq_pending);
if (xhci->xhc_state & XHCI_STATE_DYING) if (xhci->xhc_state & XHCI_STATE_DYING)
xhci_dbg(xhci, "xHCI dying, ignoring interrupt. " xhci_dbg(xhci, "xHCI dying, ignoring interrupt. "
...@@ -2103,8 +2102,6 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd) ...@@ -2103,8 +2102,6 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd)
/* Clear the event handler busy flag (RW1C); event ring is empty. */ /* Clear the event handler busy flag (RW1C); event ring is empty. */
temp_64 = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue); temp_64 = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue);
xhci_write_64(xhci, temp_64 | ERST_EHB, &xhci->ir_set->erst_dequeue); xhci_write_64(xhci, temp_64 | ERST_EHB, &xhci->ir_set->erst_dequeue);
/* Flush posted writes -- FIXME is this necessary? */
xhci_readl(xhci, &xhci->ir_set->irq_pending);
spin_unlock(&xhci->lock); spin_unlock(&xhci->lock);
return IRQ_HANDLED; return IRQ_HANDLED;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment