summaryrefslogtreecommitdiff
path: root/drivers/usb/host/xhci-hub.c
diff options
context:
space:
mode:
authorAndiry Xu <andiry.xu@amd.com>2011-09-23 14:19:52 -0700
committerGreg Kroah-Hartman <gregkh@suse.de>2011-09-26 15:51:10 -0700
commit65580b4321eb36f16ae8b5987bfa1bb948fc5112 (patch)
tree12735f923ad670c405efb5ab34c188dc06ad15f7 /drivers/usb/host/xhci-hub.c
parent9574323c39d1f8359a04843075d89c9f32d8b7e6 (diff)
xHCI: set USB2 hardware LPM
If the device pass the USB2 software LPM and the host supports hardware LPM, enable hardware LPM for the device to let the host decide when to put the link into lower power state. If hardware LPM is enabled for a port and driver wants to put it into suspend, it must first disable hardware LPM, resume the port into U0, and then suspend the port. Signed-off-by: Andiry Xu <andiry.xu@amd.com> Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/host/xhci-hub.c')
-rw-r--r--drivers/usb/host/xhci-hub.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index d7be6d7324d3..9f844d45c667 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -574,10 +574,19 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
switch (wValue) {
case USB_PORT_FEAT_SUSPEND:
temp = xhci_readl(xhci, port_array[wIndex]);
+ if ((temp & PORT_PLS_MASK) != XDEV_U0) {
+ /* Resume the port to U0 first */
+ xhci_set_link_state(xhci, port_array, wIndex,
+ XDEV_U0);
+ spin_unlock_irqrestore(&xhci->lock, flags);
+ msleep(10);
+ spin_lock_irqsave(&xhci->lock, flags);
+ }
/* In spec software should not attempt to suspend
* a port unless the port reports that it is in the
* enabled (PED = ‘1’,PLS < ‘3’) state.
*/
+ temp = xhci_readl(xhci, port_array[wIndex]);
if ((temp & PORT_PE) == 0 || (temp & PORT_RESET)
|| (temp & PORT_PLS_MASK) >= XDEV_U3) {
xhci_warn(xhci, "USB core suspending device "