aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorSarah Sharp <sarah.a.sharp@linux.intel.com>2010-07-30 01:12:38 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2010-08-10 17:35:44 -0400
commitbda531452c143b0bafe3dd6567dbfe9274009345 (patch)
tree9296a8b324357a017d70c5aa7e49741dfeb45616 /drivers/usb
parent9032cd52798daf4cd6314ffea5030b37b3eb34af (diff)
USB: xhci: Performance - move xhci_work() into xhci_irq()
When we move xhci_work() into xhci_irq(), we don't need to read the operational register status field twice. 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')
-rw-r--r--drivers/usb/host/xhci-ring.c73
1 files changed, 30 insertions, 43 deletions
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 4b50a02ba114..f9c08d2fe33a 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -2030,48 +2030,6 @@ void xhci_handle_event(struct xhci_hcd *xhci)
2030 /* Are there more items on the event ring? */ 2030 /* Are there more items on the event ring? */
2031 xhci_handle_event(xhci); 2031 xhci_handle_event(xhci);
2032} 2032}
2033/*
2034 * Called in interrupt context when there might be work
2035 * queued on the event ring
2036 *
2037 * xhci->lock must be held by caller.
2038 */
2039static void xhci_work(struct xhci_hcd *xhci)
2040{
2041 u32 temp;
2042 u64 temp_64;
2043
2044 /*
2045 * Clear the op reg interrupt status first,
2046 * so we can receive interrupts from other MSI-X interrupters.
2047 * Write 1 to clear the interrupt status.
2048 */
2049 temp = xhci_readl(xhci, &xhci->op_regs->status);
2050 temp |= STS_EINT;
2051 xhci_writel(xhci, temp, &xhci->op_regs->status);
2052 /* FIXME when MSI-X is supported and there are multiple vectors */
2053 /* Clear the MSI-X event interrupt status */
2054
2055 /* Acknowledge the interrupt */
2056 temp = xhci_readl(xhci, &xhci->ir_set->irq_pending);
2057 temp |= 0x3;
2058 xhci_writel(xhci, temp, &xhci->ir_set->irq_pending);
2059
2060 if (xhci->xhc_state & XHCI_STATE_DYING)
2061 xhci_dbg(xhci, "xHCI dying, ignoring interrupt. "
2062 "Shouldn't IRQs be disabled?\n");
2063 else
2064 /* FIXME this should be a delayed service routine
2065 * that clears the EHB.
2066 */
2067 xhci_handle_event(xhci);
2068
2069 /* Clear the event handler busy flag (RW1C); event ring is empty. */
2070 temp_64 = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue);
2071 xhci_write_64(xhci, temp_64 | ERST_EHB, &xhci->ir_set->erst_dequeue);
2072 /* Flush posted writes -- FIXME is this necessary? */
2073 xhci_readl(xhci, &xhci->ir_set->irq_pending);
2074}
2075 2033
2076/* 2034/*
2077 * xHCI spec says we can get an interrupt, and if the HC has an error condition, 2035 * xHCI spec says we can get an interrupt, and if the HC has an error condition,
@@ -2083,6 +2041,7 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd)
2083 struct xhci_hcd *xhci = hcd_to_xhci(hcd); 2041 struct xhci_hcd *xhci = hcd_to_xhci(hcd);
2084 u32 temp, temp2; 2042 u32 temp, temp2;
2085 union xhci_trb *trb; 2043 union xhci_trb *trb;
2044 u64 temp_64;
2086 2045
2087 spin_lock(&xhci->lock); 2046 spin_lock(&xhci->lock);
2088 trb = xhci->event_ring->dequeue; 2047 trb = xhci->event_ring->dequeue;
@@ -2117,7 +2076,35 @@ hw_died:
2117 return -ESHUTDOWN; 2076 return -ESHUTDOWN;
2118 } 2077 }
2119 2078
2120 xhci_work(xhci); 2079 /*
2080 * Clear the op reg interrupt status first,
2081 * so we can receive interrupts from other MSI-X interrupters.
2082 * Write 1 to clear the interrupt status.
2083 */
2084 temp |= STS_EINT;
2085 xhci_writel(xhci, temp, &xhci->op_regs->status);
2086 /* FIXME when MSI-X is supported and there are multiple vectors */
2087 /* Clear the MSI-X event interrupt status */
2088
2089 /* Acknowledge the interrupt */
2090 temp = xhci_readl(xhci, &xhci->ir_set->irq_pending);
2091 temp |= 0x3;
2092 xhci_writel(xhci, temp, &xhci->ir_set->irq_pending);
2093
2094 if (xhci->xhc_state & XHCI_STATE_DYING)
2095 xhci_dbg(xhci, "xHCI dying, ignoring interrupt. "
2096 "Shouldn't IRQs be disabled?\n");
2097 else
2098 /* FIXME this should be a delayed service routine
2099 * that clears the EHB.
2100 */
2101 xhci_handle_event(xhci);
2102
2103 /* Clear the event handler busy flag (RW1C); event ring is empty. */
2104 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);
2106 /* Flush posted writes -- FIXME is this necessary? */
2107 xhci_readl(xhci, &xhci->ir_set->irq_pending);
2121 spin_unlock(&xhci->lock); 2108 spin_unlock(&xhci->lock);
2122 2109
2123 return IRQ_HANDLED; 2110 return IRQ_HANDLED;