|
@@ -3875,17 +3875,30 @@ static void usb_enable_link_state(struct usb_hcd *hcd, struct usb_device *udev,
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- if (usb_set_lpm_timeout(udev, state, timeout))
|
|
|
+ if (usb_set_lpm_timeout(udev, state, timeout)) {
|
|
|
/* If we can't set the parent hub U1/U2 timeout,
|
|
|
* device-initiated LPM won't be allowed either, so let the xHCI
|
|
|
* host know that this link state won't be enabled.
|
|
|
*/
|
|
|
hcd->driver->disable_usb3_lpm_timeout(hcd, udev, state);
|
|
|
+ } else {
|
|
|
+ /* Only a configured device will accept the Set Feature
|
|
|
+ * U1/U2_ENABLE
|
|
|
+ */
|
|
|
+ if (udev->actconfig)
|
|
|
+ usb_set_device_initiated_lpm(udev, state, true);
|
|
|
|
|
|
- /* Only a configured device will accept the Set Feature U1/U2_ENABLE */
|
|
|
- else if (udev->actconfig)
|
|
|
- usb_set_device_initiated_lpm(udev, state, true);
|
|
|
-
|
|
|
+ /* As soon as usb_set_lpm_timeout(timeout) returns 0, the
|
|
|
+ * hub-initiated LPM is enabled. Thus, LPM is enabled no
|
|
|
+ * matter the result of usb_set_device_initiated_lpm().
|
|
|
+ * The only difference is whether device is able to initiate
|
|
|
+ * LPM.
|
|
|
+ */
|
|
|
+ if (state == USB3_LPM_U1)
|
|
|
+ udev->usb3_lpm_u1_enabled = 1;
|
|
|
+ else if (state == USB3_LPM_U2)
|
|
|
+ udev->usb3_lpm_u2_enabled = 1;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/*
|
|
@@ -3925,6 +3938,18 @@ static int usb_disable_link_state(struct usb_hcd *hcd, struct usb_device *udev,
|
|
|
dev_warn(&udev->dev, "Could not disable xHCI %s timeout, "
|
|
|
"bus schedule bandwidth may be impacted.\n",
|
|
|
usb3_lpm_names[state]);
|
|
|
+
|
|
|
+ /* As soon as usb_set_lpm_timeout(0) return 0, hub initiated LPM
|
|
|
+ * is disabled. Hub will disallows link to enter U1/U2 as well,
|
|
|
+ * even device is initiating LPM. Hence LPM is disabled if hub LPM
|
|
|
+ * timeout set to 0, no matter device-initiated LPM is disabled or
|
|
|
+ * not.
|
|
|
+ */
|
|
|
+ if (state == USB3_LPM_U1)
|
|
|
+ udev->usb3_lpm_u1_enabled = 0;
|
|
|
+ else if (state == USB3_LPM_U2)
|
|
|
+ udev->usb3_lpm_u2_enabled = 0;
|
|
|
+
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -3959,8 +3984,6 @@ 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:
|
|
@@ -4018,8 +4041,6 @@ 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);
|
|
|
|