Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

usb: host: xhci-sideband: delegate offload_usage tracking to class drivers

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>

authored by

Guan-Yu Lin and committed by
Greg Kroah-Hartman
5abbe6ec bd3d245b

+10 -14
+1 -13
drivers/usb/host/xhci-sideband.c
··· 93 93 static void 94 94 __xhci_sideband_remove_interrupter(struct xhci_sideband *sb) 95 95 { 96 - struct usb_device *udev; 97 - 98 96 lockdep_assert_held(&sb->mutex); 99 97 100 98 if (!sb->ir) ··· 100 102 101 103 xhci_remove_secondary_interrupter(xhci_to_hcd(sb->xhci), sb->ir); 102 104 sb->ir = NULL; 103 - udev = sb->vdev->udev; 104 - 105 - if (udev->state != USB_STATE_NOTATTACHED) 106 - usb_offload_put(udev); 107 105 } 108 106 109 107 /* sideband api functions */ ··· 322 328 xhci_sideband_create_interrupter(struct xhci_sideband *sb, int num_seg, 323 329 bool ip_autoclear, u32 imod_interval, int intr_num) 324 330 { 325 - int ret = 0; 326 - struct usb_device *udev; 327 - 328 331 if (!sb || !sb->xhci) 329 332 return -ENODEV; 330 333 ··· 339 348 if (!sb->ir) 340 349 return -ENOMEM; 341 350 342 - udev = sb->vdev->udev; 343 - ret = usb_offload_get(udev); 344 - 345 351 sb->ir->ip_autoclear = ip_autoclear; 346 352 347 - return ret; 353 + return 0; 348 354 } 349 355 EXPORT_SYMBOL_GPL(xhci_sideband_create_interrupter); 350 356
+9 -1
sound/usb/qcom/qc_audio_offload.c
··· 699 699 uaudio_iommu_unmap(MEM_EVENT_RING, IOVA_BASE, PAGE_SIZE, 700 700 PAGE_SIZE); 701 701 xhci_sideband_remove_interrupter(uadev[dev->chip->card->number].sb); 702 + usb_offload_put(dev->udev); 702 703 } 703 704 } 704 705 ··· 1183 1182 dma_coherent = dev_is_dma_coherent(subs->dev->bus->sysdev); 1184 1183 er_pa = 0; 1185 1184 1185 + ret = usb_offload_get(subs->dev); 1186 + if (ret < 0) 1187 + goto exit; 1188 + 1186 1189 /* event ring */ 1187 1190 ret = xhci_sideband_create_interrupter(uadev[card_num].sb, 1, false, 1188 1191 0, uaudio_qdev->data->intr_num); 1189 1192 if (ret < 0) { 1190 1193 dev_err(&subs->dev->dev, "failed to fetch interrupter\n"); 1191 - goto exit; 1194 + goto put_offload; 1192 1195 } 1193 1196 1194 1197 sgt = xhci_sideband_get_event_buffer(uadev[card_num].sb); ··· 1224 1219 mem_info->dma = 0; 1225 1220 remove_interrupter: 1226 1221 xhci_sideband_remove_interrupter(uadev[card_num].sb); 1222 + put_offload: 1223 + usb_offload_put(subs->dev); 1227 1224 exit: 1228 1225 return ret; 1229 1226 } ··· 1489 1482 uaudio_iommu_unmap(MEM_EVENT_RING, IOVA_BASE, PAGE_SIZE, PAGE_SIZE); 1490 1483 free_sec_ring: 1491 1484 xhci_sideband_remove_interrupter(uadev[card_num].sb); 1485 + usb_offload_put(subs->dev); 1492 1486 drop_sync_ep: 1493 1487 if (subs->sync_endpoint) { 1494 1488 uaudio_iommu_unmap(MEM_XFER_RING,