Commit 5abbe6ec authored by Guan-Yu Lin's avatar Guan-Yu Lin Committed by Greg Kroah-Hartman
Browse files

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: ef82a480 ("xhci: sideband: add api to trace sideband usage")
Signed-off-by: default avatarGuan-Yu Lin <guanyulin@google.com>
Tested-by: default avatarHailong Liu <hailong.liu@oppo.com>
Tested-by: default avatar <hailong.liu@oppo.com>
Acked-by: default avatarMathias Nyman <mathias.nyman@linux.intel.com>
Link: https://patch.msgid.link/20260401123238.3790062-3-guanyulin@google.com


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent bd3d245b
Loading
Loading
Loading
Loading
+1 −13
Original line number Diff line number Diff line
@@ -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);

+9 −1
Original line number Diff line number Diff line
@@ -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 @@ static int uaudio_event_ring_setup(struct snd_usb_substream *subs,
	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 @@ static int prepare_qmi_response(struct snd_usb_substream *subs,
	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,