diff options
| -rw-r--r-- | drivers/usb/host/xhci-ring.c | 50 |
1 files changed, 37 insertions, 13 deletions
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 3b962ba5ef08..7dfd17707d53 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c | |||
| @@ -1184,7 +1184,6 @@ static void handle_port_status(struct xhci_hcd *xhci, | |||
| 1184 | 1184 | ||
| 1185 | /* Update event ring dequeue pointer before dropping the lock */ | 1185 | /* Update event ring dequeue pointer before dropping the lock */ |
| 1186 | inc_deq(xhci, xhci->event_ring, true); | 1186 | inc_deq(xhci, xhci->event_ring, true); |
| 1187 | xhci_set_hc_event_deq(xhci); | ||
| 1188 | 1187 | ||
| 1189 | spin_unlock(&xhci->lock); | 1188 | spin_unlock(&xhci->lock); |
| 1190 | /* Pass this up to the core */ | 1189 | /* Pass this up to the core */ |
| @@ -1924,7 +1923,6 @@ cleanup: | |||
| 1924 | */ | 1923 | */ |
| 1925 | if (trb_comp_code == COMP_MISSED_INT || !ep->skip) { | 1924 | if (trb_comp_code == COMP_MISSED_INT || !ep->skip) { |
| 1926 | inc_deq(xhci, xhci->event_ring, true); | 1925 | inc_deq(xhci, xhci->event_ring, true); |
| 1927 | xhci_set_hc_event_deq(xhci); | ||
| 1928 | } | 1926 | } |
| 1929 | 1927 | ||
| 1930 | if (ret) { | 1928 | if (ret) { |
| @@ -2022,11 +2020,10 @@ static void xhci_handle_event(struct xhci_hcd *xhci) | |||
| 2022 | return; | 2020 | return; |
| 2023 | } | 2021 | } |
| 2024 | 2022 | ||
| 2025 | if (update_ptrs) { | 2023 | if (update_ptrs) |
| 2026 | /* Update SW and HC event ring dequeue pointer */ | 2024 | /* Update SW event ring dequeue pointer */ |
| 2027 | inc_deq(xhci, xhci->event_ring, true); | 2025 | inc_deq(xhci, xhci->event_ring, true); |
| 2028 | xhci_set_hc_event_deq(xhci); | 2026 | |
| 2029 | } | ||
| 2030 | /* Are there more items on the event ring? */ | 2027 | /* Are there more items on the event ring? */ |
| 2031 | xhci_handle_event(xhci); | 2028 | xhci_handle_event(xhci); |
| 2032 | } | 2029 | } |
| @@ -2042,6 +2039,8 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd) | |||
| 2042 | u32 status, irq_pending; | 2039 | u32 status, irq_pending; |
| 2043 | union xhci_trb *trb; | 2040 | union xhci_trb *trb; |
| 2044 | u64 temp_64; | 2041 | u64 temp_64; |
| 2042 | union xhci_trb *event_ring_deq; | ||
| 2043 | dma_addr_t deq; | ||
| 2045 | 2044 | ||
| 2046 | spin_lock(&xhci->lock); | 2045 | spin_lock(&xhci->lock); |
| 2047 | trb = xhci->event_ring->dequeue; | 2046 | trb = xhci->event_ring->dequeue; |
| @@ -2090,18 +2089,43 @@ hw_died: | |||
| 2090 | irq_pending |= 0x3; | 2089 | irq_pending |= 0x3; |
| 2091 | xhci_writel(xhci, irq_pending, &xhci->ir_set->irq_pending); | 2090 | xhci_writel(xhci, irq_pending, &xhci->ir_set->irq_pending); |
| 2092 | 2091 | ||
| 2093 | if (xhci->xhc_state & XHCI_STATE_DYING) | 2092 | if (xhci->xhc_state & XHCI_STATE_DYING) { |
| 2094 | xhci_dbg(xhci, "xHCI dying, ignoring interrupt. " | 2093 | xhci_dbg(xhci, "xHCI dying, ignoring interrupt. " |
| 2095 | "Shouldn't IRQs be disabled?\n"); | 2094 | "Shouldn't IRQs be disabled?\n"); |
| 2096 | else | 2095 | /* Clear the event handler busy flag (RW1C); |
| 2097 | /* FIXME this should be a delayed service routine | 2096 | * the event ring should be empty. |
| 2098 | * that clears the EHB. | ||
| 2099 | */ | 2097 | */ |
| 2100 | xhci_handle_event(xhci); | 2098 | temp_64 = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue); |
| 2099 | xhci_write_64(xhci, temp_64 | ERST_EHB, | ||
| 2100 | &xhci->ir_set->erst_dequeue); | ||
| 2101 | spin_unlock(&xhci->lock); | ||
| 2102 | |||
| 2103 | return IRQ_HANDLED; | ||
| 2104 | } | ||
| 2105 | |||
| 2106 | event_ring_deq = xhci->event_ring->dequeue; | ||
| 2107 | /* FIXME this should be a delayed service routine | ||
| 2108 | * that clears the EHB. | ||
| 2109 | */ | ||
| 2110 | xhci_handle_event(xhci); | ||
| 2101 | 2111 | ||
| 2102 | /* Clear the event handler busy flag (RW1C); event ring is empty. */ | ||
| 2103 | temp_64 = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue); | 2112 | temp_64 = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue); |
| 2104 | xhci_write_64(xhci, temp_64 | ERST_EHB, &xhci->ir_set->erst_dequeue); | 2113 | /* If necessary, update the HW's version of the event ring deq ptr. */ |
| 2114 | if (event_ring_deq != xhci->event_ring->dequeue) { | ||
| 2115 | deq = xhci_trb_virt_to_dma(xhci->event_ring->deq_seg, | ||
| 2116 | xhci->event_ring->dequeue); | ||
| 2117 | if (deq == 0) | ||
| 2118 | xhci_warn(xhci, "WARN something wrong with SW event " | ||
| 2119 | "ring dequeue ptr.\n"); | ||
| 2120 | /* Update HC event ring dequeue pointer */ | ||
| 2121 | temp_64 &= ERST_PTR_MASK; | ||
| 2122 | temp_64 |= ((u64) deq & (u64) ~ERST_PTR_MASK); | ||
| 2123 | } | ||
| 2124 | |||
| 2125 | /* Clear the event handler busy flag (RW1C); event ring is empty. */ | ||
| 2126 | temp_64 |= ERST_EHB; | ||
| 2127 | xhci_write_64(xhci, temp_64, &xhci->ir_set->erst_dequeue); | ||
| 2128 | |||
| 2105 | spin_unlock(&xhci->lock); | 2129 | spin_unlock(&xhci->lock); |
| 2106 | 2130 | ||
| 2107 | return IRQ_HANDLED; | 2131 | return IRQ_HANDLED; |
