usb: add usb2 Link PM variables to sysfs and usb_device
Adds abitilty to tune L1 timeout (inactivity timer for usb2 link sleep) and BESL (best effort service latency)via sysfs. This also adds a new usb2_lpm_parameters structure with those variables to struct usb_device. Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com> Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
This commit is contained in:
parent
a558ccdcc7
commit
17f34867e9
@ -236,3 +236,30 @@ Description:
|
||||
This attribute is to expose these information to user space.
|
||||
The file will read "hotplug", "wired" and "not used" if the
|
||||
information is available, and "unknown" otherwise.
|
||||
|
||||
What: /sys/bus/usb/devices/.../power/usb2_lpm_l1_timeout
|
||||
Date: May 2013
|
||||
Contact: Mathias Nyman <mathias.nyman@linux.intel.com>
|
||||
Description:
|
||||
USB 2.0 devices may support hardware link power management (LPM)
|
||||
L1 sleep state. The usb2_lpm_l1_timeout attribute allows
|
||||
tuning the timeout for L1 inactivity timer (LPM timer), e.g.
|
||||
needed inactivity time before host requests the device to go to L1 sleep.
|
||||
Useful for power management tuning.
|
||||
Supported values are 0 - 65535 microseconds.
|
||||
|
||||
What: /sys/bus/usb/devices/.../power/usb2_lpm_besl
|
||||
Date: May 2013
|
||||
Contact: Mathias Nyman <mathias.nyman@linux.intel.com>
|
||||
Description:
|
||||
USB 2.0 devices that support hardware link power management (LPM)
|
||||
L1 sleep state now use a best effort service latency value (BESL) to
|
||||
indicate the best effort to resumption of service to the device after the
|
||||
initiation of the resume event.
|
||||
If the device does not have a preferred besl value then the host can select
|
||||
one instead. This usb2_lpm_besl attribute allows to tune the host selected besl
|
||||
value in order to tune power saving and service latency.
|
||||
|
||||
Supported values are 0 - 15.
|
||||
More information on how besl values map to microseconds can be found in
|
||||
USB 2.0 ECN Errata for Link Power Management, section 4.10)
|
||||
|
@ -497,8 +497,62 @@ set_usb2_hardware_lpm(struct device *dev, struct device_attribute *attr,
|
||||
static DEVICE_ATTR(usb2_hardware_lpm, S_IRUGO | S_IWUSR, show_usb2_hardware_lpm,
|
||||
set_usb2_hardware_lpm);
|
||||
|
||||
static ssize_t
|
||||
show_usb2_lpm_l1_timeout(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct usb_device *udev = to_usb_device(dev);
|
||||
return sprintf(buf, "%d\n", udev->l1_params.timeout);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
set_usb2_lpm_l1_timeout(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct usb_device *udev = to_usb_device(dev);
|
||||
u16 timeout;
|
||||
|
||||
if (kstrtou16(buf, 0, &timeout))
|
||||
return -EINVAL;
|
||||
|
||||
udev->l1_params.timeout = timeout;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(usb2_lpm_l1_timeout, S_IRUGO | S_IWUSR,
|
||||
show_usb2_lpm_l1_timeout, set_usb2_lpm_l1_timeout);
|
||||
|
||||
static ssize_t
|
||||
show_usb2_lpm_besl(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct usb_device *udev = to_usb_device(dev);
|
||||
return sprintf(buf, "%d\n", udev->l1_params.besl);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
set_usb2_lpm_besl(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct usb_device *udev = to_usb_device(dev);
|
||||
u8 besl;
|
||||
|
||||
if (kstrtou8(buf, 0, &besl) || besl > 15)
|
||||
return -EINVAL;
|
||||
|
||||
udev->l1_params.besl = besl;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(usb2_lpm_besl, S_IRUGO | S_IWUSR,
|
||||
show_usb2_lpm_besl, set_usb2_lpm_besl);
|
||||
|
||||
static struct attribute *usb2_hardware_lpm_attr[] = {
|
||||
&dev_attr_usb2_hardware_lpm.attr,
|
||||
&dev_attr_usb2_lpm_l1_timeout.attr,
|
||||
&dev_attr_usb2_lpm_besl.attr,
|
||||
NULL,
|
||||
};
|
||||
static struct attribute_group usb2_hardware_lpm_attr_group = {
|
||||
|
@ -3917,7 +3917,7 @@ static int xhci_calculate_usb2_hw_lpm_params(struct usb_device *udev)
|
||||
field = le32_to_cpu(udev->bos->ext_cap->bmAttributes);
|
||||
|
||||
/* xHCI l1 is set in steps of 256us, xHCI 1.0 section 5.4.11.2 */
|
||||
l1 = XHCI_L1_TIMEOUT / 256;
|
||||
l1 = udev->l1_params.timeout / 256;
|
||||
|
||||
/* device has preferred BESLD */
|
||||
if (field & USB_BESL_DEEP_VALID) {
|
||||
@ -4101,7 +4101,7 @@ int xhci_set_usb2_hardware_lpm(struct usb_hcd *hcd,
|
||||
(field & USB_BESL_BASELINE_VALID))
|
||||
hird = USB_GET_BESL_BASELINE(field);
|
||||
else
|
||||
hird = XHCI_DEFAULT_BESL;
|
||||
hird = udev->l1_params.besl;
|
||||
|
||||
exit_latency = xhci_besl_encoding[hird];
|
||||
spin_unlock_irqrestore(&xhci->lock, flags);
|
||||
@ -4191,6 +4191,8 @@ int xhci_update_device(struct usb_hcd *hcd, struct usb_device *udev)
|
||||
if (xhci->hw_lpm_support == 1 &&
|
||||
xhci_check_usb2_port_capability(xhci, portnum, XHCI_HLC)) {
|
||||
udev->usb2_hw_lpm_capable = 1;
|
||||
udev->l1_params.timeout = XHCI_L1_TIMEOUT;
|
||||
udev->l1_params.besl = XHCI_DEFAULT_BESL;
|
||||
if (xhci_check_usb2_port_capability(xhci, portnum,
|
||||
XHCI_BLC))
|
||||
udev->usb2_hw_lpm_besl_capable = 1;
|
||||
|
@ -393,6 +393,22 @@ enum usb_port_connect_type {
|
||||
USB_PORT_NOT_USED,
|
||||
};
|
||||
|
||||
/*
|
||||
* USB 2.0 Link Power Management (LPM) parameters.
|
||||
*/
|
||||
struct usb2_lpm_parameters {
|
||||
/* Best effort service latency indicate how long the host will drive
|
||||
* resume on an exit from L1.
|
||||
*/
|
||||
unsigned int besl;
|
||||
|
||||
/* Timeout value in microseconds for the L1 inactivity (LPM) timer.
|
||||
* When the timer counts to zero, the parent hub will initiate a LPM
|
||||
* transition to L1.
|
||||
*/
|
||||
int timeout;
|
||||
};
|
||||
|
||||
/*
|
||||
* USB 3.0 Link Power Management (LPM) parameters.
|
||||
*
|
||||
@ -488,6 +504,7 @@ struct usb3_lpm_parameters {
|
||||
* specific data for the device.
|
||||
* @slot_id: Slot ID assigned by xHCI
|
||||
* @removable: Device can be physically removed from this port
|
||||
* @l1_params: best effor service latency for USB2 L1 LPM state, and L1 timeout.
|
||||
* @u1_params: exit latencies for USB3 U1 LPM state, and hub-initiated timeout.
|
||||
* @u2_params: exit latencies for USB3 U2 LPM state, and hub-initiated timeout.
|
||||
* @lpm_disable_count: Ref count used by usb_disable_lpm() and usb_enable_lpm()
|
||||
@ -568,6 +585,7 @@ struct usb_device {
|
||||
struct wusb_dev *wusb_dev;
|
||||
int slot_id;
|
||||
enum usb_device_removable removable;
|
||||
struct usb2_lpm_parameters l1_params;
|
||||
struct usb3_lpm_parameters u1_params;
|
||||
struct usb3_lpm_parameters u2_params;
|
||||
unsigned lpm_disable_count;
|
||||
|
Loading…
Reference in New Issue
Block a user