Commit de3edd47 authored by Uday M Bhat's avatar Uday M Bhat Committed by Greg Kroah-Hartman
Browse files

xhci: dbc: Allow users to modify DbC poll interval via sysfs



xhci DbC driver polls the host controller for DbC events at a reduced
rate when DbC is enabled but there are no active data transfers.

Allow users to modify this reduced poll interval via dbc_poll_interval_ms
sysfs entry. Unit is milliseconds and accepted range is 0 to 5000.
Max interval of 5000 ms is selected as it matches the common 5 second
timeout used in usb stack.
Default value is 64 milliseconds.

A long interval is useful when users know there won't be any activity
on systems connected via DbC for long periods, and want to avoid
battery drainage due to unnecessary CPU usage.

Example being Android Debugger (ADB) usage over DbC on ChromeOS systems
running Android Runtime.

[minor changes and rewording -Mathias]

Co-developed-by: default avatarSamuel Jacob <samjaco@google.com>
Signed-off-by: default avatarSamuel Jacob <samjaco@google.com>
Signed-off-by: default avatarUday M Bhat <uday.m.bhat@intel.com>
Signed-off-by: default avatarMathias Nyman <mathias.nyman@linux.intel.com>
Link: https://lore.kernel.org/r/20240626124835.1023046-5-mathias.nyman@linux.intel.com


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 7b59c036
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -75,3 +75,13 @@ Description:
		The default value is 1  (GNU Remote Debug command).
		Other permissible value is 0 which is for vendor defined debug
		target.

What:		/sys/bus/pci/drivers/xhci_hcd/.../dbc_poll_interval_ms
Date:		February 2024
Contact:	Mathias Nyman <mathias.nyman@linux.intel.com>
Description:
		This attribute adjust the polling interval used to check for
		DbC events. Unit is milliseconds. Accepted values range from 0
		up to 5000. The default value is 64 ms.
		This polling interval is used while DbC is enabled but has no
		active data transfers.
+38 −0
Original line number Diff line number Diff line
@@ -1150,11 +1150,48 @@ static ssize_t dbc_bInterfaceProtocol_store(struct device *dev,
	return size;
}

static ssize_t dbc_poll_interval_ms_show(struct device *dev,
					 struct device_attribute *attr,
					 char *buf)
{
	struct xhci_dbc *dbc;
	struct xhci_hcd *xhci;

	xhci = hcd_to_xhci(dev_get_drvdata(dev));
	dbc = xhci->dbc;

	return sysfs_emit(buf, "%u\n", dbc->poll_interval);
}

static ssize_t dbc_poll_interval_ms_store(struct device *dev,
					  struct device_attribute *attr,
					  const char *buf, size_t size)
{
	struct xhci_dbc *dbc;
	struct xhci_hcd *xhci;
	u32 value;
	int ret;

	ret = kstrtou32(buf, 0, &value);
	if (ret || value > DBC_POLL_INTERVAL_MAX)
		return -EINVAL;

	xhci = hcd_to_xhci(dev_get_drvdata(dev));
	dbc = xhci->dbc;

	dbc->poll_interval = value;

	mod_delayed_work(system_wq, &dbc->event_work, 0);

	return size;
}

static DEVICE_ATTR_RW(dbc);
static DEVICE_ATTR_RW(dbc_idVendor);
static DEVICE_ATTR_RW(dbc_idProduct);
static DEVICE_ATTR_RW(dbc_bcdDevice);
static DEVICE_ATTR_RW(dbc_bInterfaceProtocol);
static DEVICE_ATTR_RW(dbc_poll_interval_ms);

static struct attribute *dbc_dev_attrs[] = {
	&dev_attr_dbc.attr,
@@ -1162,6 +1199,7 @@ static struct attribute *dbc_dev_attrs[] = {
	&dev_attr_dbc_idProduct.attr,
	&dev_attr_dbc_bcdDevice.attr,
	&dev_attr_dbc_bInterfaceProtocol.attr,
	&dev_attr_dbc_poll_interval_ms.attr,
	NULL
};
ATTRIBUTE_GROUPS(dbc_dev);
+1 −1
Original line number Diff line number Diff line
@@ -95,7 +95,7 @@ struct dbc_ep {
#define DBC_QUEUE_SIZE			16
#define DBC_WRITE_BUF_SIZE		8192
#define DBC_POLL_INTERVAL_DEFAULT	64	/* milliseconds */

#define DBC_POLL_INTERVAL_MAX		5000	/* milliseconds */
/*
 * Private structure for DbC hardware state:
 */