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

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: 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>

authored by

Uday M Bhat and committed by
Greg Kroah-Hartman
de3edd47 7b59c036

+49 -1
+10
Documentation/ABI/testing/sysfs-bus-pci-drivers-xhci_hcd
··· 75 75 The default value is 1 (GNU Remote Debug command). 76 76 Other permissible value is 0 which is for vendor defined debug 77 77 target. 78 + 79 + What: /sys/bus/pci/drivers/xhci_hcd/.../dbc_poll_interval_ms 80 + Date: February 2024 81 + Contact: Mathias Nyman <mathias.nyman@linux.intel.com> 82 + Description: 83 + This attribute adjust the polling interval used to check for 84 + DbC events. Unit is milliseconds. Accepted values range from 0 85 + up to 5000. The default value is 64 ms. 86 + This polling interval is used while DbC is enabled but has no 87 + active data transfers.
+38
drivers/usb/host/xhci-dbgcap.c
··· 1150 1150 return size; 1151 1151 } 1152 1152 1153 + static ssize_t dbc_poll_interval_ms_show(struct device *dev, 1154 + struct device_attribute *attr, 1155 + char *buf) 1156 + { 1157 + struct xhci_dbc *dbc; 1158 + struct xhci_hcd *xhci; 1159 + 1160 + xhci = hcd_to_xhci(dev_get_drvdata(dev)); 1161 + dbc = xhci->dbc; 1162 + 1163 + return sysfs_emit(buf, "%u\n", dbc->poll_interval); 1164 + } 1165 + 1166 + static ssize_t dbc_poll_interval_ms_store(struct device *dev, 1167 + struct device_attribute *attr, 1168 + const char *buf, size_t size) 1169 + { 1170 + struct xhci_dbc *dbc; 1171 + struct xhci_hcd *xhci; 1172 + u32 value; 1173 + int ret; 1174 + 1175 + ret = kstrtou32(buf, 0, &value); 1176 + if (ret || value > DBC_POLL_INTERVAL_MAX) 1177 + return -EINVAL; 1178 + 1179 + xhci = hcd_to_xhci(dev_get_drvdata(dev)); 1180 + dbc = xhci->dbc; 1181 + 1182 + dbc->poll_interval = value; 1183 + 1184 + mod_delayed_work(system_wq, &dbc->event_work, 0); 1185 + 1186 + return size; 1187 + } 1188 + 1153 1189 static DEVICE_ATTR_RW(dbc); 1154 1190 static DEVICE_ATTR_RW(dbc_idVendor); 1155 1191 static DEVICE_ATTR_RW(dbc_idProduct); 1156 1192 static DEVICE_ATTR_RW(dbc_bcdDevice); 1157 1193 static DEVICE_ATTR_RW(dbc_bInterfaceProtocol); 1194 + static DEVICE_ATTR_RW(dbc_poll_interval_ms); 1158 1195 1159 1196 static struct attribute *dbc_dev_attrs[] = { 1160 1197 &dev_attr_dbc.attr, ··· 1199 1162 &dev_attr_dbc_idProduct.attr, 1200 1163 &dev_attr_dbc_bcdDevice.attr, 1201 1164 &dev_attr_dbc_bInterfaceProtocol.attr, 1165 + &dev_attr_dbc_poll_interval_ms.attr, 1202 1166 NULL 1203 1167 }; 1204 1168 ATTRIBUTE_GROUPS(dbc_dev);
+1 -1
drivers/usb/host/xhci-dbgcap.h
··· 95 95 #define DBC_QUEUE_SIZE 16 96 96 #define DBC_WRITE_BUF_SIZE 8192 97 97 #define DBC_POLL_INTERVAL_DEFAULT 64 /* milliseconds */ 98 - 98 + #define DBC_POLL_INTERVAL_MAX 5000 /* milliseconds */ 99 99 /* 100 100 * Private structure for DbC hardware state: 101 101 */