usbcore: add sysfs support to xHCI usb3 hardware LPM
Add a sysfs node to make it easier to verify if LPM is supported and being enabled for USB 3.0 devices. Signed-off-by: Kevin Strasser <kevin.strasser@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
eb4861c3ce
commit
655fe4effe
|
@ -114,6 +114,20 @@ Description:
|
|||
enabled for the device. Developer can write y/Y/1 or n/N/0 to
|
||||
the file to enable/disable the feature.
|
||||
|
||||
What: /sys/bus/usb/devices/.../power/usb3_hardware_lpm
|
||||
Date: June 2015
|
||||
Contact: Kevin Strasser <kevin.strasser@linux.intel.com>
|
||||
Description:
|
||||
If CONFIG_PM_RUNTIME is set and a USB 3.0 lpm-capable device is
|
||||
plugged in to a xHCI host which supports link PM, it will check
|
||||
if U1 and U2 exit latencies have been set in the BOS
|
||||
descriptor; if the check is is passed and the host supports
|
||||
USB3 hardware LPM, USB3 hardware LPM will be enabled for the
|
||||
device and the USB device directory will contain a file named
|
||||
power/usb3_hardware_lpm. The file holds a string value (enable
|
||||
or disable) indicating whether or not USB3 hardware LPM is
|
||||
enabled for the device.
|
||||
|
||||
What: /sys/bus/usb/devices/.../removable
|
||||
Date: February 2012
|
||||
Contact: Matthew Garrett <mjg@redhat.com>
|
||||
|
|
|
@ -521,10 +521,10 @@ enabling hardware LPM, the host can automatically put the device into
|
|||
lower power state(L1 for usb2.0 devices, or U1/U2 for usb3.0 devices),
|
||||
which state device can enter and resume very quickly.
|
||||
|
||||
The user interface for controlling USB2 hardware LPM is located in the
|
||||
The user interface for controlling hardware LPM is located in the
|
||||
power/ subdirectory of each USB device's sysfs directory, that is, in
|
||||
/sys/bus/usb/devices/.../power/ where "..." is the device's ID. The
|
||||
relevant attribute files is usb2_hardware_lpm.
|
||||
relevant attribute files are usb2_hardware_lpm and usb3_hardware_lpm.
|
||||
|
||||
power/usb2_hardware_lpm
|
||||
|
||||
|
@ -537,6 +537,17 @@ relevant attribute files is usb2_hardware_lpm.
|
|||
can write y/Y/1 or n/N/0 to the file to enable/disable
|
||||
USB2 hardware LPM manually. This is for test purpose mainly.
|
||||
|
||||
power/usb3_hardware_lpm
|
||||
|
||||
When a USB 3.0 lpm-capable device is plugged in to a
|
||||
xHCI host which supports link PM, it will check if U1
|
||||
and U2 exit latencies have been set in the BOS
|
||||
descriptor; if the check is is passed and the host
|
||||
supports USB3 hardware LPM, USB3 hardware LPM will be
|
||||
enabled for the device and this file will be created.
|
||||
The file holds a string value (enable or disable)
|
||||
indicating whether or not USB3 hardware LPM is
|
||||
enabled for the device.
|
||||
|
||||
USB Port Power Control
|
||||
----------------------
|
||||
|
|
|
@ -3950,6 +3950,8 @@ int usb_disable_lpm(struct usb_device *udev)
|
|||
if (usb_disable_link_state(hcd, udev, USB3_LPM_U2))
|
||||
goto enable_lpm;
|
||||
|
||||
udev->usb3_lpm_enabled = 0;
|
||||
|
||||
return 0;
|
||||
|
||||
enable_lpm:
|
||||
|
@ -4007,6 +4009,8 @@ void usb_enable_lpm(struct usb_device *udev)
|
|||
|
||||
usb_enable_link_state(hcd, udev, USB3_LPM_U1);
|
||||
usb_enable_link_state(hcd, udev, USB3_LPM_U2);
|
||||
|
||||
udev->usb3_lpm_enabled = 1;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(usb_enable_lpm);
|
||||
|
||||
|
|
|
@ -531,6 +531,25 @@ static ssize_t usb2_lpm_besl_store(struct device *dev,
|
|||
}
|
||||
static DEVICE_ATTR_RW(usb2_lpm_besl);
|
||||
|
||||
static ssize_t usb3_hardware_lpm_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct usb_device *udev = to_usb_device(dev);
|
||||
const char *p;
|
||||
|
||||
usb_lock_device(udev);
|
||||
|
||||
if (udev->usb3_lpm_enabled)
|
||||
p = "enabled";
|
||||
else
|
||||
p = "disabled";
|
||||
|
||||
usb_unlock_device(udev);
|
||||
|
||||
return sprintf(buf, "%s\n", p);
|
||||
}
|
||||
static DEVICE_ATTR_RO(usb3_hardware_lpm);
|
||||
|
||||
static struct attribute *usb2_hardware_lpm_attr[] = {
|
||||
&dev_attr_usb2_hardware_lpm.attr,
|
||||
&dev_attr_usb2_lpm_l1_timeout.attr,
|
||||
|
@ -542,6 +561,15 @@ static struct attribute_group usb2_hardware_lpm_attr_group = {
|
|||
.attrs = usb2_hardware_lpm_attr,
|
||||
};
|
||||
|
||||
static struct attribute *usb3_hardware_lpm_attr[] = {
|
||||
&dev_attr_usb3_hardware_lpm.attr,
|
||||
NULL,
|
||||
};
|
||||
static struct attribute_group usb3_hardware_lpm_attr_group = {
|
||||
.name = power_group_name,
|
||||
.attrs = usb3_hardware_lpm_attr,
|
||||
};
|
||||
|
||||
static struct attribute *power_attrs[] = {
|
||||
&dev_attr_autosuspend.attr,
|
||||
&dev_attr_level.attr,
|
||||
|
@ -564,6 +592,9 @@ static int add_power_attributes(struct device *dev)
|
|||
if (udev->usb2_hw_lpm_capable == 1)
|
||||
rc = sysfs_merge_group(&dev->kobj,
|
||||
&usb2_hardware_lpm_attr_group);
|
||||
if (udev->lpm_capable == 1)
|
||||
rc = sysfs_merge_group(&dev->kobj,
|
||||
&usb3_hardware_lpm_attr_group);
|
||||
}
|
||||
|
||||
return rc;
|
||||
|
|
Loading…
Reference in New Issue
Block a user