summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNiklas Neronin <niklas.neronin@linux.intel.com>2025-05-15 16:56:11 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2025-05-21 12:35:32 +0200
commit1fdeb069053f65e974c6fd945c85fcb854e6c199 (patch)
tree0808971e367a4fb04b62965c730cfcc75ece94b9
parent3d5b8a0e0af4df8fe70b244a5d84a559b6ad5558 (diff)
usb: xhci: set requested IMODI to the closest supported value
The function configures the Interrupt Moderation Interval (IMODI) via bits 15:0 in the Interrupt Moderation Register. The IMODI value is specified in increments of 250 nanoseconds. For instance, an IMODI register value of 16 corresponds to 4000 nanoseconds, resulting in an interrupt every ~1ms. Currently, the function fails when a requested IMODI value is too large, only logging a warning message for secondary interrupters. Prevent this by automatically adjusting the IMODI value to the nearest supported value. 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-15-mathias.nyman@linux.intel.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/usb/host/xhci-mem.c5
-rw-r--r--drivers/usb/host/xhci.c7
2 files changed, 6 insertions, 6 deletions
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 08513e5d321a..dcfe7774e9ed 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -2393,10 +2393,7 @@ xhci_create_secondary_interrupter(struct usb_hcd *hcd, unsigned int segs,
return NULL;
}
- err = xhci_set_interrupter_moderation(ir, imod_interval);
- if (err)
- xhci_warn(xhci, "Failed to set interrupter %d moderation to %uns\n",
- i, imod_interval);
+ xhci_set_interrupter_moderation(ir, imod_interval);
xhci_dbg(xhci, "Add secondary interrupter %d, max interrupters %d\n",
ir->intr_num, xhci->max_interrupters);
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index c6b517401c94..c3a1a67b6563 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -355,12 +355,15 @@ int xhci_set_interrupter_moderation(struct xhci_interrupter *ir,
{
u32 imod;
- if (!ir || !ir->ir_set || imod_interval > U16_MAX * 250)
+ if (!ir || !ir->ir_set)
return -EINVAL;
+ /* IMODI value in IMOD register is in 250ns increments */
+ imod_interval = umin(imod_interval / 250, ER_IRQ_INTERVAL_MASK);
+
imod = readl(&ir->ir_set->irq_control);
imod &= ~ER_IRQ_INTERVAL_MASK;
- imod |= (imod_interval / 250) & ER_IRQ_INTERVAL_MASK;
+ imod |= imod_interval;
writel(imod, &ir->ir_set->irq_control);
return 0;