xhci: Add helper to set an interrupters interrupt moderation interval
Add a helper to set the interrupt moderation interval for an interrupter. Each interrupter can have its own moderation value. Hardware has a 16bit register for the moderation value, each step is 250ns. Helper function imod_interval argument is in nanoseconds. Values from 0 to 16383750 (250 x 0xffff) are accepted. 0 means no interrupt throttling. 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-3-quic_wcheng@quicinc.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
4f022aad80
commit
ace2162587
@ -346,6 +346,23 @@ static int xhci_disable_interrupter(struct xhci_interrupter *ir)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* interrupt moderation interval imod_interval in nanoseconds */
|
||||
static int xhci_set_interrupter_moderation(struct xhci_interrupter *ir,
|
||||
u32 imod_interval)
|
||||
{
|
||||
u32 imod;
|
||||
|
||||
if (!ir || !ir->ir_set || imod_interval > U16_MAX * 250)
|
||||
return -EINVAL;
|
||||
|
||||
imod = readl(&ir->ir_set->irq_control);
|
||||
imod &= ~ER_IRQ_INTERVAL_MASK;
|
||||
imod |= (imod_interval / 250) & ER_IRQ_INTERVAL_MASK;
|
||||
writel(imod, &ir->ir_set->irq_control);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void compliance_mode_recovery(struct timer_list *t)
|
||||
{
|
||||
struct xhci_hcd *xhci;
|
||||
@ -528,7 +545,6 @@ static int xhci_run_finished(struct xhci_hcd *xhci)
|
||||
*/
|
||||
int xhci_run(struct usb_hcd *hcd)
|
||||
{
|
||||
u32 temp;
|
||||
u64 temp_64;
|
||||
int ret;
|
||||
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
|
||||
@ -551,12 +567,7 @@ int xhci_run(struct usb_hcd *hcd)
|
||||
xhci_dbg_trace(xhci, trace_xhci_dbg_init,
|
||||
"ERST deq = 64'h%0lx", (long unsigned int) temp_64);
|
||||
|
||||
xhci_dbg_trace(xhci, trace_xhci_dbg_init,
|
||||
"// Set the interrupt modulation register");
|
||||
temp = readl(&ir->ir_set->irq_control);
|
||||
temp &= ~ER_IRQ_INTERVAL_MASK;
|
||||
temp |= (xhci->imod_interval / 250) & ER_IRQ_INTERVAL_MASK;
|
||||
writel(temp, &ir->ir_set->irq_control);
|
||||
xhci_set_interrupter_moderation(ir, xhci->imod_interval);
|
||||
|
||||
if (xhci->quirks & XHCI_NEC_HOST) {
|
||||
struct xhci_command *command;
|
||||
|
Loading…
x
Reference in New Issue
Block a user