]> git.itanic.dy.fi Git - linux-stable/commitdiff
xhci: remove unnecessary event_ring_deq parameter from xhci_handle_event()
authorMathias Nyman <mathias.nyman@linux.intel.com>
Sat, 17 Feb 2024 00:09:30 +0000 (16:09 -0800)
committerSasha Levin <sashal@kernel.org>
Tue, 26 Mar 2024 22:17:29 +0000 (18:17 -0400)
[ Upstream commit 143e64df1bda33310c30ba5e15f72022e6135939 ]

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>
Stable-dep-of: e30e9ad9ed66 ("xhci: update event ring dequeue pointer position to controller correctly")
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/usb/host/xhci-ring.c

index 53852383d6143a4615715436d4061ed639e5426b..129d2e83034c1d97ee326083f87c36a5d838754d 100644 (file)
@@ -3038,30 +3038,26 @@ static int xhci_handle_event(struct xhci_hcd *xhci, struct xhci_interrupter *ir)
  */
 static void xhci_update_erst_dequeue(struct xhci_hcd *xhci,
                                     struct xhci_interrupter *ir,
-                                    union xhci_trb *event_ring_deq,
                                     bool clear_ehb)
 {
        u64 temp_64;
        dma_addr_t deq;
 
        temp_64 = xhci_read_64(xhci, &ir->ir_set->erst_dequeue);
-       /* If necessary, update the HW's version of the event ring deq ptr. */
-       if (event_ring_deq != ir->event_ring->dequeue) {
-               deq = xhci_trb_virt_to_dma(ir->event_ring->deq_seg,
-                               ir->event_ring->dequeue);
-               if (deq == 0)
-                       xhci_warn(xhci, "WARN something wrong with SW event ring dequeue ptr\n");
-               /*
-                * Per 4.9.4, Software writes to the ERDP register shall
-                * always advance the Event Ring Dequeue Pointer value.
-                */
-               if ((temp_64 & ERST_PTR_MASK) == (deq & ERST_PTR_MASK))
-                       return;
+       deq = xhci_trb_virt_to_dma(ir->event_ring->deq_seg,
+                                  ir->event_ring->dequeue);
+       if (deq == 0)
+               xhci_warn(xhci, "WARN something wrong with SW event ring dequeue ptr\n");
+       /*
+        * Per 4.9.4, Software writes to the ERDP register shall always advance
+        * the Event Ring Dequeue Pointer value.
+        */
+       if ((temp_64 & ERST_PTR_MASK) == (deq & ERST_PTR_MASK) && !clear_ehb)
+               return;
 
-               /* Update HC event ring dequeue pointer */
-               temp_64 = ir->event_ring->deq_seg->num & ERST_DESI_MASK;
-               temp_64 |= deq & ERST_PTR_MASK;
-       }
+       /* Update HC event ring dequeue pointer */
+       temp_64 = ir->event_ring->deq_seg->num & ERST_DESI_MASK;
+       temp_64 |= deq & ERST_PTR_MASK;
 
        /* Clear the event handler busy flag (RW1C) */
        if (clear_ehb)
@@ -3090,7 +3086,6 @@ static void xhci_clear_interrupt_pending(struct xhci_hcd *xhci,
 irqreturn_t xhci_irq(struct usb_hcd *hcd)
 {
        struct xhci_hcd *xhci = hcd_to_xhci(hcd);
-       union xhci_trb *event_ring_deq;
        struct xhci_interrupter *ir;
        irqreturn_t ret = IRQ_NONE;
        u64 temp_64;
@@ -3148,15 +3143,13 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd)
                goto out;
        }
 
-       event_ring_deq = ir->event_ring->dequeue;
        /* FIXME this should be a delayed service routine
         * that clears the EHB.
         */
        while (xhci_handle_event(xhci, ir) > 0) {
                if (event_loop++ < TRBS_PER_SEGMENT / 2)
                        continue;
-               xhci_update_erst_dequeue(xhci, ir, event_ring_deq, false);
-               event_ring_deq = ir->event_ring->dequeue;
+               xhci_update_erst_dequeue(xhci, ir, false);
 
                /* ring is half-full, force isoc trbs to interrupt more often */
                if (ir->isoc_bei_interval > AVOID_BEI_INTERVAL_MIN)
@@ -3165,7 +3158,7 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd)
                event_loop = 0;
        }
 
-       xhci_update_erst_dequeue(xhci, ir, event_ring_deq, true);
+       xhci_update_erst_dequeue(xhci, ir, true);
        ret = IRQ_HANDLED;
 
 out: