aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host
diff options
context:
space:
mode:
authorSarah Sharp <sarah.a.sharp@linux.intel.com>2010-07-30 01:12:43 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2010-08-10 17:35:44 -0400
commit27e0dd4d7ccc3e8e2a79600c3608031022a2298c (patch)
tree0121f9f0a3de32ce09c4b26cf3b56284176994f7 /drivers/usb/host
parentbda531452c143b0bafe3dd6567dbfe9274009345 (diff)
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: Sarah Sharp <sarah.a.sharp@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/host')
-rw-r--r--drivers/usb/host/xhci-ring.c27
1 files changed, 12 insertions, 15 deletions
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index f9c08d2fe33a..eb4b10229a05 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -2039,25 +2039,25 @@ void xhci_handle_event(struct xhci_hcd *xhci)
2039irqreturn_t xhci_irq(struct usb_hcd *hcd) 2039irqreturn_t xhci_irq(struct usb_hcd *hcd)
2040{ 2040{
2041 struct xhci_hcd *xhci = hcd_to_xhci(hcd); 2041 struct xhci_hcd *xhci = hcd_to_xhci(hcd);
2042 u32 temp, temp2; 2042 u32 status, irq_pending;
2043 union xhci_trb *trb; 2043 union xhci_trb *trb;
2044 u64 temp_64; 2044 u64 temp_64;
2045 2045
2046 spin_lock(&xhci->lock); 2046 spin_lock(&xhci->lock);
2047 trb = xhci->event_ring->dequeue; 2047 trb = xhci->event_ring->dequeue;
2048 /* Check if the xHC generated the interrupt, or the irq is shared */ 2048 /* Check if the xHC generated the interrupt, or the irq is shared */
2049 temp = xhci_readl(xhci, &xhci->op_regs->status); 2049 status = xhci_readl(xhci, &xhci->op_regs->status);
2050 temp2 = xhci_readl(xhci, &xhci->ir_set->irq_pending); 2050 irq_pending = xhci_readl(xhci, &xhci->ir_set->irq_pending);
2051 if (temp == 0xffffffff && temp2 == 0xffffffff) 2051 if (status == 0xffffffff && irq_pending == 0xffffffff)
2052 goto hw_died; 2052 goto hw_died;
2053 2053
2054 if (!(temp & STS_EINT) && !ER_IRQ_PENDING(temp2)) { 2054 if (!(status & STS_EINT) && !ER_IRQ_PENDING(irq_pending)) {
2055 spin_unlock(&xhci->lock); 2055 spin_unlock(&xhci->lock);
2056 xhci_warn(xhci, "Spurious interrupt.\n"); 2056 xhci_warn(xhci, "Spurious interrupt.\n");
2057 return IRQ_NONE; 2057 return IRQ_NONE;
2058 } 2058 }
2059 xhci_dbg(xhci, "op reg status = %08x\n", temp); 2059 xhci_dbg(xhci, "op reg status = %08x\n", status);
2060 xhci_dbg(xhci, "ir set irq_pending = %08x\n", temp2); 2060 xhci_dbg(xhci, "ir set irq_pending = %08x\n", irq_pending);
2061 xhci_dbg(xhci, "Event ring dequeue ptr:\n"); 2061 xhci_dbg(xhci, "Event ring dequeue ptr:\n");
2062 xhci_dbg(xhci, "@%llx %08x %08x %08x %08x\n", 2062 xhci_dbg(xhci, "@%llx %08x %08x %08x %08x\n",
2063 (unsigned long long) 2063 (unsigned long long)
@@ -2067,7 +2067,7 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd)
2067 (unsigned int) trb->link.intr_target, 2067 (unsigned int) trb->link.intr_target,
2068 (unsigned int) trb->link.control); 2068 (unsigned int) trb->link.control);
2069 2069
2070 if (temp & STS_FATAL) { 2070 if (status & STS_FATAL) {
2071 xhci_warn(xhci, "WARNING: Host System Error\n"); 2071 xhci_warn(xhci, "WARNING: Host System Error\n");
2072 xhci_halt(xhci); 2072 xhci_halt(xhci);
2073hw_died: 2073hw_died:
@@ -2081,15 +2081,14 @@ hw_died:
2081 * so we can receive interrupts from other MSI-X interrupters. 2081 * so we can receive interrupts from other MSI-X interrupters.
2082 * Write 1 to clear the interrupt status. 2082 * Write 1 to clear the interrupt status.
2083 */ 2083 */
2084 temp |= STS_EINT; 2084 status |= STS_EINT;
2085 xhci_writel(xhci, temp, &xhci->op_regs->status); 2085 xhci_writel(xhci, status, &xhci->op_regs->status);
2086 /* FIXME when MSI-X is supported and there are multiple vectors */ 2086 /* FIXME when MSI-X is supported and there are multiple vectors */
2087 /* Clear the MSI-X event interrupt status */ 2087 /* Clear the MSI-X event interrupt status */
2088 2088
2089 /* Acknowledge the interrupt */ 2089 /* Acknowledge the interrupt */
2090 temp = xhci_readl(xhci, &xhci->ir_set->irq_pending); 2090 irq_pending |= 0x3;
2091 temp |= 0x3; 2091 xhci_writel(xhci, irq_pending, &xhci->ir_set->irq_pending);
2092 xhci_writel(xhci, temp, &xhci->ir_set->irq_pending);
2093 2092
2094 if (xhci->xhc_state & XHCI_STATE_DYING) 2093 if (xhci->xhc_state & XHCI_STATE_DYING)
2095 xhci_dbg(xhci, "xHCI dying, ignoring interrupt. " 2094 xhci_dbg(xhci, "xHCI dying, ignoring interrupt. "
@@ -2103,8 +2102,6 @@ hw_died:
2103 /* Clear the event handler busy flag (RW1C); event ring is empty. */ 2102 /* Clear the event handler busy flag (RW1C); event ring is empty. */
2104 temp_64 = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue); 2103 temp_64 = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue);
2105 xhci_write_64(xhci, temp_64 | ERST_EHB, &xhci->ir_set->erst_dequeue); 2104 xhci_write_64(xhci, temp_64 | ERST_EHB, &xhci->ir_set->erst_dequeue);
2106 /* Flush posted writes -- FIXME is this necessary? */
2107 xhci_readl(xhci, &xhci->ir_set->irq_pending);
2108 spin_unlock(&xhci->lock); 2105 spin_unlock(&xhci->lock);
2109 2106
2110 return IRQ_HANDLED; 2107 return IRQ_HANDLED;