diff options
author | Sarah Sharp <sarah.a.sharp@linux.intel.com> | 2010-07-30 01:12:38 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-08-10 17:35:44 -0400 |
commit | bda531452c143b0bafe3dd6567dbfe9274009345 (patch) | |
tree | 9296a8b324357a017d70c5aa7e49741dfeb45616 /drivers/usb | |
parent | 9032cd52798daf4cd6314ffea5030b37b3eb34af (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.c | 73 |
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 | */ | ||
2039 | static 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; |