summaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/xhci.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host/xhci.c')
-rw-r--r--drivers/usb/host/xhci.c54
1 files changed, 21 insertions, 33 deletions
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 8579603eda..0a8cf6c17f 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -1125,10 +1125,20 @@ int xhci_resume(struct xhci_hcd *xhci, pm_message_t msg)
xhci_dbg(xhci, "Start the secondary HCD\n");
retval = xhci_run(xhci->shared_hcd);
}
-
+ if (retval)
+ return retval;
+ /*
+ * Resume roothubs unconditionally as PORTSC change bits are not
+ * immediately visible after xHC reset
+ */
hcd->state = HC_STATE_SUSPENDED;
- if (xhci->shared_hcd)
+
+ if (xhci->shared_hcd) {
xhci->shared_hcd->state = HC_STATE_SUSPENDED;
+ usb_hcd_resume_root_hub(xhci->shared_hcd);
+ }
+ usb_hcd_resume_root_hub(hcd);
+
goto done;
}
@@ -1152,7 +1162,6 @@ int xhci_resume(struct xhci_hcd *xhci, pm_message_t msg)
xhci_dbc_resume(xhci);
- done:
if (retval == 0) {
/*
* Resume roothubs only if there are pending events.
@@ -1178,6 +1187,7 @@ int xhci_resume(struct xhci_hcd *xhci, pm_message_t msg)
usb_hcd_resume_root_hub(hcd);
}
}
+done:
/*
* If system is subject to the Quirk, Compliance Mode Timer needs to
* be re-initialized Always after a system resume. Ports are subject
@@ -4507,35 +4517,13 @@ static int xhci_set_usb2_hardware_lpm(struct usb_hcd *hcd,
return 0;
}
-/* check if a usb2 port supports a given extened capability protocol
- * only USB2 ports extended protocol capability values are cached.
- * Return 1 if capability is supported
- */
-static int xhci_check_usb2_port_capability(struct xhci_hcd *xhci, int port,
- unsigned capability)
-{
- u32 port_offset, port_count;
- int i;
-
- for (i = 0; i < xhci->num_ext_caps; i++) {
- if (xhci->ext_caps[i] & capability) {
- /* port offsets starts at 1 */
- port_offset = XHCI_EXT_PORT_OFF(xhci->ext_caps[i]) - 1;
- port_count = XHCI_EXT_PORT_COUNT(xhci->ext_caps[i]);
- if (port >= port_offset &&
- port < port_offset + port_count)
- return 1;
- }
- }
- return 0;
-}
-
static int xhci_update_device(struct usb_hcd *hcd, struct usb_device *udev)
{
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
- int portnum = udev->portnum - 1;
+ struct xhci_port *port;
+ u32 capability;
- if (hcd->speed >= HCD_USB3 || !udev->lpm_capable)
+ if (hcd->speed >= HCD_USB3 || !udev->lpm_capable || !xhci->hw_lpm_support)
return 0;
/* we only support lpm for non-hub device connected to root hub yet */
@@ -4543,14 +4531,14 @@ static int xhci_update_device(struct usb_hcd *hcd, struct usb_device *udev)
udev->descriptor.bDeviceClass == USB_CLASS_HUB)
return 0;
- if (xhci->hw_lpm_support == 1 &&
- xhci_check_usb2_port_capability(
- xhci, portnum, XHCI_HLC)) {
+ port = xhci->usb2_rhub.ports[udev->portnum - 1];
+ capability = port->port_cap->protocol_caps;
+
+ if (capability & 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))
+ if (capability & XHCI_BLC)
udev->usb2_hw_lpm_besl_capable = 1;
}