]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
usb: host: xhci-sideband: delegate offload_usage tracking to class drivers
authorGuan-Yu Lin <guanyulin@google.com>
Wed, 1 Apr 2026 12:32:18 +0000 (12:32 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 2 Apr 2026 07:43:30 +0000 (09:43 +0200)
Remove usb_offload_get() and usb_offload_put() from the xHCI sideband
interrupter creation and removal paths.

The responsibility of manipulating offload_usage now lies entirely with
the USB class drivers. They have the precise context of when an offload
data stream actually starts and stops, ensuring a much more accurate
representation of offload activity for power management.

Cc: stable <stable@kernel.org>
Fixes: ef82a4803aab ("xhci: sideband: add api to trace sideband usage")
Signed-off-by: Guan-Yu Lin <guanyulin@google.com>
Tested-by: Hailong Liu <hailong.liu@oppo.com>
Tested-by: hailong.liu@oppo.com
Acked-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Link: https://patch.msgid.link/20260401123238.3790062-3-guanyulin@google.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/host/xhci-sideband.c
sound/usb/qcom/qc_audio_offload.c

index 54284d29d2016c9399ffa29833cdbce81ad8df0e..23153e136d4b842b7740453d07bf9b6a713b7d7e 100644 (file)
@@ -93,8 +93,6 @@ __xhci_sideband_remove_endpoint(struct xhci_sideband *sb, struct xhci_virt_ep *e
 static void
 __xhci_sideband_remove_interrupter(struct xhci_sideband *sb)
 {
-       struct usb_device *udev;
-
        lockdep_assert_held(&sb->mutex);
 
        if (!sb->ir)
@@ -102,10 +100,6 @@ __xhci_sideband_remove_interrupter(struct xhci_sideband *sb)
 
        xhci_remove_secondary_interrupter(xhci_to_hcd(sb->xhci), sb->ir);
        sb->ir = NULL;
-       udev = sb->vdev->udev;
-
-       if (udev->state != USB_STATE_NOTATTACHED)
-               usb_offload_put(udev);
 }
 
 /* sideband api functions */
@@ -328,9 +322,6 @@ int
 xhci_sideband_create_interrupter(struct xhci_sideband *sb, int num_seg,
                                 bool ip_autoclear, u32 imod_interval, int intr_num)
 {
-       int ret = 0;
-       struct usb_device *udev;
-
        if (!sb || !sb->xhci)
                return -ENODEV;
 
@@ -348,12 +339,9 @@ xhci_sideband_create_interrupter(struct xhci_sideband *sb, int num_seg,
        if (!sb->ir)
                return -ENOMEM;
 
-       udev = sb->vdev->udev;
-       ret = usb_offload_get(udev);
-
        sb->ir->ip_autoclear = ip_autoclear;
 
-       return ret;
+       return 0;
 }
 EXPORT_SYMBOL_GPL(xhci_sideband_create_interrupter);
 
index 510b68cced33c19a5c6cd5144626380b538e9441..a8d313fa254ac2617113eb1d5f3c32a1a7cd2f30 100644 (file)
@@ -699,6 +699,7 @@ static void uaudio_event_ring_cleanup_free(struct uaudio_dev *dev)
                uaudio_iommu_unmap(MEM_EVENT_RING, IOVA_BASE, PAGE_SIZE,
                                   PAGE_SIZE);
                xhci_sideband_remove_interrupter(uadev[dev->chip->card->number].sb);
+               usb_offload_put(dev->udev);
        }
 }
 
@@ -1182,12 +1183,16 @@ static int uaudio_event_ring_setup(struct snd_usb_substream *subs,
        dma_coherent = dev_is_dma_coherent(subs->dev->bus->sysdev);
        er_pa = 0;
 
+       ret = usb_offload_get(subs->dev);
+       if (ret < 0)
+               goto exit;
+
        /* event ring */
        ret = xhci_sideband_create_interrupter(uadev[card_num].sb, 1, false,
                                               0, uaudio_qdev->data->intr_num);
        if (ret < 0) {
                dev_err(&subs->dev->dev, "failed to fetch interrupter\n");
-               goto exit;
+               goto put_offload;
        }
 
        sgt = xhci_sideband_get_event_buffer(uadev[card_num].sb);
@@ -1219,6 +1224,8 @@ clear_pa:
        mem_info->dma = 0;
 remove_interrupter:
        xhci_sideband_remove_interrupter(uadev[card_num].sb);
+put_offload:
+       usb_offload_put(subs->dev);
 exit:
        return ret;
 }
@@ -1482,6 +1489,7 @@ unmap_er:
        uaudio_iommu_unmap(MEM_EVENT_RING, IOVA_BASE, PAGE_SIZE, PAGE_SIZE);
 free_sec_ring:
        xhci_sideband_remove_interrupter(uadev[card_num].sb);
+       usb_offload_put(subs->dev);
 drop_sync_ep:
        if (subs->sync_endpoint) {
                uaudio_iommu_unmap(MEM_XFER_RING,