xhci: dbc: Allow users to modify DbC poll interval via sysfs
authorUday M Bhat <uday.m.bhat@intel.com>
Wed, 26 Jun 2024 12:48:18 +0000 (15:48 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 27 Jun 2024 14:08:05 +0000 (16:08 +0200)
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: Samuel Jacob <samjaco@google.com>
Signed-off-by: Samuel Jacob <samjaco@google.com>
Signed-off-by: Uday M Bhat <uday.m.bhat@intel.com>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Link: https://lore.kernel.org/r/20240626124835.1023046-5-mathias.nyman@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Documentation/ABI/testing/sysfs-bus-pci-drivers-xhci_hcd
drivers/usb/host/xhci-dbgcap.c
drivers/usb/host/xhci-dbgcap.h

index 5a775b8f654351b29bfcacfb0d1c10afe217ad62..fc82aa4e54b005e67a6224c113337c0d4636bfcb 100644 (file)
@@ -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.
index 872d9cddbcefa0e3695325022726b4bcff146b5c..161c09953c4e08851d1a6a933363380194b1a9ee 100644 (file)
@@ -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);
index 92661b555c2a29db77b78ac75f593f71fe8cc689..0118c6288a3ccec9b5b9f544d116046fb7149a27 100644 (file)
@@ -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:
  */