Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

xhci: remove unnecessary event_ring_deq parameter from xhci_handle_event()

The event_ring_deq parameter is used to check if the event ring dequeue
position is updated while calling by xhci_handle_event(), meaning there was
an actual event on the ring to handle. In this case the driver needs to
inform hardware about the updated dequeue position.
Basically event_ring_deq just stores the old event ring dequeue position
before calling the event handler.

Keeping track of software event dequeue updates this way is no longer
useful as driver anyways reads the current hardware dequeue position
within the handle event, and checks if it needs to be updated.

The driver might anyway need to modify the EHB (event handler busy) bit in
the same register as the dequeue pointer even if the actual dequeue
position did not change.

Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Signed-off-by: Wesley Cheng <quic_wcheng@quicinc.com>
Link: https://lore.kernel.org/r/20240217001017.29969-5-quic_wcheng@quicinc.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Mathias Nyman and committed by
Greg Kroah-Hartman
143e64df becbd202

+15 -22
+15 -22
drivers/usb/host/xhci-ring.c
··· 3032 3032 */ 3033 3033 static void xhci_update_erst_dequeue(struct xhci_hcd *xhci, 3034 3034 struct xhci_interrupter *ir, 3035 - union xhci_trb *event_ring_deq, 3036 3035 bool clear_ehb) 3037 3036 { 3038 3037 u64 temp_64; 3039 3038 dma_addr_t deq; 3040 3039 3041 3040 temp_64 = xhci_read_64(xhci, &ir->ir_set->erst_dequeue); 3042 - /* If necessary, update the HW's version of the event ring deq ptr. */ 3043 - if (event_ring_deq != ir->event_ring->dequeue) { 3044 - deq = xhci_trb_virt_to_dma(ir->event_ring->deq_seg, 3045 - ir->event_ring->dequeue); 3046 - if (deq == 0) 3047 - xhci_warn(xhci, "WARN something wrong with SW event ring dequeue ptr\n"); 3048 - /* 3049 - * Per 4.9.4, Software writes to the ERDP register shall 3050 - * always advance the Event Ring Dequeue Pointer value. 3051 - */ 3052 - if ((temp_64 & ERST_PTR_MASK) == (deq & ERST_PTR_MASK)) 3053 - return; 3041 + deq = xhci_trb_virt_to_dma(ir->event_ring->deq_seg, 3042 + ir->event_ring->dequeue); 3043 + if (deq == 0) 3044 + xhci_warn(xhci, "WARN something wrong with SW event ring dequeue ptr\n"); 3045 + /* 3046 + * Per 4.9.4, Software writes to the ERDP register shall always advance 3047 + * the Event Ring Dequeue Pointer value. 3048 + */ 3049 + if ((temp_64 & ERST_PTR_MASK) == (deq & ERST_PTR_MASK) && !clear_ehb) 3050 + return; 3054 3051 3055 - /* Update HC event ring dequeue pointer */ 3056 - temp_64 = ir->event_ring->deq_seg->num & ERST_DESI_MASK; 3057 - temp_64 |= deq & ERST_PTR_MASK; 3058 - } 3052 + /* Update HC event ring dequeue pointer */ 3053 + temp_64 = ir->event_ring->deq_seg->num & ERST_DESI_MASK; 3054 + temp_64 |= deq & ERST_PTR_MASK; 3059 3055 3060 3056 /* Clear the event handler busy flag (RW1C) */ 3061 3057 if (clear_ehb) ··· 3080 3084 irqreturn_t xhci_irq(struct usb_hcd *hcd) 3081 3085 { 3082 3086 struct xhci_hcd *xhci = hcd_to_xhci(hcd); 3083 - union xhci_trb *event_ring_deq; 3084 3087 struct xhci_interrupter *ir; 3085 3088 irqreturn_t ret = IRQ_NONE; 3086 3089 u64 temp_64; ··· 3137 3142 goto out; 3138 3143 } 3139 3144 3140 - event_ring_deq = ir->event_ring->dequeue; 3141 3145 /* FIXME this should be a delayed service routine 3142 3146 * that clears the EHB. 3143 3147 */ 3144 3148 while (xhci_handle_event(xhci, ir) > 0) { 3145 3149 if (event_loop++ < TRBS_PER_SEGMENT / 2) 3146 3150 continue; 3147 - xhci_update_erst_dequeue(xhci, ir, event_ring_deq, false); 3148 - event_ring_deq = ir->event_ring->dequeue; 3151 + xhci_update_erst_dequeue(xhci, ir, false); 3149 3152 3150 3153 /* ring is half-full, force isoc trbs to interrupt more often */ 3151 3154 if (ir->isoc_bei_interval > AVOID_BEI_INTERVAL_MIN) ··· 3152 3159 event_loop = 0; 3153 3160 } 3154 3161 3155 - xhci_update_erst_dequeue(xhci, ir, event_ring_deq, true); 3162 + xhci_update_erst_dequeue(xhci, ir, true); 3156 3163 ret = IRQ_HANDLED; 3157 3164 3158 3165 out: