]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
xhci: support setting interrupt moderation IMOD for secondary interrupters
authorMathias Nyman <mathias.nyman@linux.intel.com>
Thu, 5 Sep 2024 14:33:00 +0000 (17:33 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 9 May 2025 07:44:06 +0000 (09:44 +0200)
[ Upstream commit 9c0c11bb87b09a8b7cdc21ca1090e7b36abe9d09 ]

Allow creators of seconday interrupters to specify the interrupt
moderation interval value in nanoseconds when creating the interrupter.

If not sure what value to use then use the xhci driver default
xhci->imod_interval

Suggested-by: Wesley Cheng <quic_wcheng@quicinc.com>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Link: https://lore.kernel.org/r/20240905143300.1959279-13-mathias.nyman@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Stable-dep-of: bea5892d0ed2 ("xhci: Limit time spent with xHC interrupts disabled during bus resume")
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/usb/host/xhci-mem.c
drivers/usb/host/xhci.c
drivers/usb/host/xhci.h

index 489f54cf9a8a22b63f35ac8ed04b6f4af71a8ac4..2c44855be75ed0cecdc0c38d7d5af39c05121eea 100644 (file)
@@ -2353,7 +2353,8 @@ xhci_add_interrupter(struct xhci_hcd *xhci, struct xhci_interrupter *ir,
 }
 
 struct xhci_interrupter *
-xhci_create_secondary_interrupter(struct usb_hcd *hcd, unsigned int segs)
+xhci_create_secondary_interrupter(struct usb_hcd *hcd, unsigned int segs,
+                                 u32 imod_interval)
 {
        struct xhci_hcd *xhci = hcd_to_xhci(hcd);
        struct xhci_interrupter *ir;
@@ -2386,6 +2387,11 @@ 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_dbg(xhci, "Add secondary interrupter %d, max interrupters %d\n",
                 i, xhci->max_interrupters);
 
index d6a0c79e5fadaf71b3891739b0752e5e1f22bb64..0af298c5af65a7ce5a608212b1ca330c104dce68 100644 (file)
@@ -324,8 +324,8 @@ static int xhci_disable_interrupter(struct xhci_interrupter *ir)
 }
 
 /* interrupt moderation interval imod_interval in nanoseconds */
-static int xhci_set_interrupter_moderation(struct xhci_interrupter *ir,
-                                          u32 imod_interval)
+int xhci_set_interrupter_moderation(struct xhci_interrupter *ir,
+                                   u32 imod_interval)
 {
        u32 imod;
 
index 156e43977cdd4365e633694e81e8feb7e2d6e767..9d05a21392bb86319f0f6611ab75fade7e71a802 100644 (file)
@@ -1867,7 +1867,8 @@ struct xhci_container_ctx *xhci_alloc_container_ctx(struct xhci_hcd *xhci,
 void xhci_free_container_ctx(struct xhci_hcd *xhci,
                struct xhci_container_ctx *ctx);
 struct xhci_interrupter *
-xhci_create_secondary_interrupter(struct usb_hcd *hcd, unsigned int segs);
+xhci_create_secondary_interrupter(struct usb_hcd *hcd, unsigned int segs,
+                                 u32 imod_interval);
 void xhci_remove_secondary_interrupter(struct usb_hcd
                                       *hcd, struct xhci_interrupter *ir);
 
@@ -1905,6 +1906,8 @@ int xhci_alloc_tt_info(struct xhci_hcd *xhci,
                struct xhci_virt_device *virt_dev,
                struct usb_device *hdev,
                struct usb_tt *tt, gfp_t mem_flags);
+int xhci_set_interrupter_moderation(struct xhci_interrupter *ir,
+                                   u32 imod_interval);
 
 /* xHCI ring, segment, TRB, and TD functions */
 dma_addr_t xhci_trb_virt_to_dma(struct xhci_segment *seg, union xhci_trb *trb);