usb: xhci: move initialization of the primary interrupter
authorNiklas Neronin <niklas.neronin@linux.intel.com>
Thu, 15 May 2025 13:56:08 +0000 (16:56 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 21 May 2025 10:35:32 +0000 (12:35 +0200)
Move the primary interrupter (0) initialization from xhci_mem_init() to
xhci_init(). This change requires us to save the allocated interrupter
somewhere before initialization. Therefore, store it in the 'interrupters'
array and rework xhci_add_interrupter() to retrieve the interrupter from
the array.

This is part of the ongoing effort to separate allocation and
initialization.

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-12-mathias.nyman@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/host/xhci-mem.c
drivers/usb/host/xhci.c
drivers/usb/host/xhci.h

index bfb01c432b231fc40abe803d401e5a389cdb3434..eb076f5ed1d0ecc2dcbcafc3c09c074b99c71de4 100644 (file)
@@ -2321,14 +2321,13 @@ xhci_alloc_interrupter(struct xhci_hcd *xhci, unsigned int segs, gfp_t flags)
        return ir;
 }
 
-static void
-xhci_add_interrupter(struct xhci_hcd *xhci, struct xhci_interrupter *ir,
-                    unsigned int intr_num)
+void xhci_add_interrupter(struct xhci_hcd *xhci, unsigned int intr_num)
 {
+       struct xhci_interrupter *ir;
        u64 erst_base;
        u32 erst_size;
 
-       xhci->interrupters[intr_num] = ir;
+       ir = xhci->interrupters[intr_num];
        ir->intr_num = intr_num;
        ir->ir_set = &xhci->run_regs->ir_set[intr_num];
 
@@ -2372,14 +2371,16 @@ xhci_create_secondary_interrupter(struct usb_hcd *hcd, unsigned int segs,
                /* Find available secondary interrupter, interrupter 0 is reserved for primary */
                for (i = 1; i < xhci->max_interrupters; i++) {
                        if (!xhci->interrupters[i]) {
-                               xhci_add_interrupter(xhci, ir, i);
+                               xhci->interrupters[i] = ir;
+                               xhci_add_interrupter(xhci, i);
                                err = 0;
                                break;
                        }
                }
        } else {
                if (!xhci->interrupters[intr_num]) {
-                       xhci_add_interrupter(xhci, ir, intr_num);
+                       xhci->interrupters[intr_num] = ir;
+                       xhci_add_interrupter(xhci, intr_num);
                        err = 0;
                }
        }
@@ -2406,7 +2407,6 @@ EXPORT_SYMBOL_GPL(xhci_create_secondary_interrupter);
 
 int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
 {
-       struct xhci_interrupter *ir;
        struct device   *dev = xhci_to_hcd(xhci)->self.sysdev;
        dma_addr_t      dma;
 
@@ -2490,14 +2490,10 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
        xhci->interrupters = kcalloc_node(xhci->max_interrupters, sizeof(*xhci->interrupters),
                                          flags, dev_to_node(dev));
 
-       ir = xhci_alloc_interrupter(xhci, 0, flags);
-       if (!ir)
+       xhci->interrupters[0] = xhci_alloc_interrupter(xhci, 0, flags);
+       if (!xhci->interrupters[0])
                goto fail;
 
-       xhci_add_interrupter(xhci, ir, 0);
-
-       ir->isoc_bei_interval = AVOID_BEI_INTERVAL_MAX;
-
        if (scratchpad_alloc(xhci, flags))
                goto fail;
        if (xhci_setup_port_arrays(xhci, flags))
index fa80cc30c3fe769cd263f21da74edd408a814bf6..c6b517401c9431ceee7a3c7af6ebf3214a14374c 100644 (file)
@@ -578,6 +578,10 @@ static int xhci_init(struct usb_hcd *hcd)
        /* Set USB 3.0 device notifications for function remote wake */
        xhci_set_dev_notifications(xhci);
 
+       /* Initialize the Primary interrupter */
+       xhci_add_interrupter(xhci, 0);
+       xhci->interrupters[0]->isoc_bei_interval = AVOID_BEI_INTERVAL_MAX;
+
        /* Initializing Compliance Mode Recovery Data If Needed */
        if (xhci_compliance_mode_recovery_timer_quirk_check()) {
                xhci->quirks |= XHCI_COMP_MODE_QUIRK;
index 31d945c4ac073572522b1e91e6e690b439abd1c4..b0b16cd7df91f41a5c675912740a05966a645cbb 100644 (file)
@@ -1959,6 +1959,7 @@ void xhci_process_cancelled_tds(struct xhci_virt_ep *ep);
 void xhci_update_erst_dequeue(struct xhci_hcd *xhci,
                              struct xhci_interrupter *ir,
                              bool clear_ehb);
+void xhci_add_interrupter(struct xhci_hcd *xhci, unsigned int intr_num);
 
 /* xHCI roothub code */
 void xhci_set_link_state(struct xhci_hcd *xhci, struct xhci_port *port,