On Thu, Jan 09, 2025 at 03:55:07AM +0000, Guan-Yu Lin wrote:
> Introduce offload_usage and corresponding apis to track offload usage
> on each USB device. Offload denotes that there is another co-processor
> accessing the USB device via the same USB host controller. To optimize
> power usage, it's essential to monitor whether the USB device is
> actively used by other co-processor. This information is vital when
> determining if a USB device can be safely suspended during system power
> state transitions.
>
> Signed-off-by: Guan-Yu Lin <guanyulin@xxxxxxxxxx>
> ---
> drivers/usb/core/driver.c | 108 ++++++++++++++++++++++++++++++++++++++
> drivers/usb/core/usb.c | 4 ++
> include/linux/usb.h | 19 +++++++
> 3 files changed, 131 insertions(+)
>
> diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
> index f203fdbfb6f6..01f6287cf73f 100644
> --- a/drivers/usb/core/driver.c
> +++ b/drivers/usb/core/driver.c
> @@ -2037,6 +2037,114 @@ int usb_disable_usb2_hardware_lpm(struct usb_device *udev)
>
> #endif /* CONFIG_PM */
>
> +#ifdef CONFIG_USB_XHCI_SIDEBAND
> +
> +/**
> + * usb_offload_get - increment the offload_usage of a USB device
> + * @udev: the USB device to increment its offload_usage
> + *
> + * Incrementing the offload_usage of a usb_device indicates that offload is
> + * enabled on this usb_device; that is, another entity is actively handling USB
> + * transfers. This information allows the USB driver to adjust its power
> + * management policy based on offload activity.
> + *
> + * The caller must hold @udev's device lock.
> + *
> + * Return: 0 on success. A negative error code otherwise.
> + */
> +int usb_offload_get(struct usb_device *udev)
> +{
> + int ret;
> +
> + if (udev->state == USB_STATE_NOTATTACHED ||
> + udev->state == USB_STATE_SUSPENDED)
> + return -EAGAIN;
> +
> + /*
> + * offload_usage could only be modified when the device is active, since
> + * it will alter the suspend flow of the device.
> + */
> + ret = pm_runtime_get_sync(&udev->dev);
Note that this function will increment the runtime PM reference count
even if it returns an error. You probably want to call
pm_runtime_resume_and_get() instead. Likewise in usb_offload_put().
> +
> + if (ret < 0)
> + return ret;
> +
> + refcount_inc(&udev->offload_usage);
> + pm_runtime_put_sync(&udev->dev);
> +
> + return 0;
> +}
> +EXPORT_SYMBOL_GPL(usb_offload_get);
Alan Stern
[Index of Archives]
[Pulseaudio]
[Linux Audio Users]
[ALSA Devel]
[Fedora Desktop]
[Fedora SELinux]
[Big List of Linux Books]
[Yosemite News]
[KDE Users]