usb: xhci: guarantee that IMAN register is flushed
authorNiklas Neronin <niklas.neronin@linux.intel.com>
Thu, 15 May 2025 13:56:13 +0000 (16:56 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 21 May 2025 10:35:33 +0000 (12:35 +0200)
Add read call to guarantee that the write to the IMAN register has
been flushed.

xHCI specification 1.2, section 5.5.2.1, Note:
"Most systems have write buffers that minimize overhead, but this may
 require a read operation to guarantee that the write has been flushed
 from the posted buffer."

Signed-off-by: Niklas Neronin <niklas.neronin@linux.intel.com>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Link: https://lore.kernel.org/r/20250515135621.335595-17-mathias.nyman@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/host/xhci-ring.c
drivers/usb/host/xhci.c

index d2002ecd27b004ba11ecf2832bf76a3a7ce39ea8..4a4410f7978f35fe24d349049959c3663688d979 100644 (file)
@@ -3087,6 +3087,9 @@ static void xhci_clear_interrupt_pending(struct xhci_interrupter *ir)
                irq_pending = readl(&ir->ir_set->irq_pending);
                irq_pending |= IMAN_IP;
                writel(irq_pending, &ir->ir_set->irq_pending);
+
+               /* Read operation to guarantee the write has been flushed from posted buffers */
+               readl(&ir->ir_set->irq_pending);
        }
 }
 
index 472589679af39546795c66276ad15e9044343a7a..8cdb1a01a3edf5f67141c714694258d68c9276e3 100644 (file)
@@ -335,6 +335,8 @@ int xhci_enable_interrupter(struct xhci_interrupter *ir)
        iman |= IMAN_IE;
        writel(iman, &ir->ir_set->irq_pending);
 
+       /* Read operation to guarantee the write has been flushed from posted buffers */
+       readl(&ir->ir_set->irq_pending);
        return 0;
 }
 
@@ -350,6 +352,7 @@ int xhci_disable_interrupter(struct xhci_interrupter *ir)
        iman &= ~IMAN_IE;
        writel(iman, &ir->ir_set->irq_pending);
 
+       readl(&ir->ir_set->irq_pending);
        return 0;
 }