|
@@ -466,7 +466,7 @@ static void compliance_mode_recovery_timer_init(struct xhci_hcd *xhci)
|
|
|
* Systems:
|
|
|
* Vendor: Hewlett-Packard -> System Models: Z420, Z620 and Z820
|
|
|
*/
|
|
|
-static bool compliance_mode_recovery_timer_quirk_check(void)
|
|
|
+bool xhci_compliance_mode_recovery_timer_quirk_check(void)
|
|
|
{
|
|
|
const char *dmi_product_name, *dmi_sys_vendor;
|
|
|
|
|
@@ -517,7 +517,7 @@ int xhci_init(struct usb_hcd *hcd)
|
|
|
xhci_dbg(xhci, "Finished xhci_init\n");
|
|
|
|
|
|
/* Initializing Compliance Mode Recovery Data If Needed */
|
|
|
- if (compliance_mode_recovery_timer_quirk_check()) {
|
|
|
+ if (xhci_compliance_mode_recovery_timer_quirk_check()) {
|
|
|
xhci->quirks |= XHCI_COMP_MODE_QUIRK;
|
|
|
compliance_mode_recovery_timer_init(xhci);
|
|
|
}
|
|
@@ -956,6 +956,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
|
|
|
struct usb_hcd *hcd = xhci_to_hcd(xhci);
|
|
|
struct usb_hcd *secondary_hcd;
|
|
|
int retval = 0;
|
|
|
+ bool comp_timer_running = false;
|
|
|
|
|
|
/* Wait a bit if either of the roothubs need to settle from the
|
|
|
* transition into bus suspend.
|
|
@@ -993,6 +994,13 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
|
|
|
|
|
|
/* If restore operation fails, re-initialize the HC during resume */
|
|
|
if ((temp & STS_SRE) || hibernated) {
|
|
|
+
|
|
|
+ if ((xhci->quirks & XHCI_COMP_MODE_QUIRK) &&
|
|
|
+ !(xhci_all_ports_seen_u0(xhci))) {
|
|
|
+ del_timer_sync(&xhci->comp_mode_recovery_timer);
|
|
|
+ xhci_dbg(xhci, "Compliance Mode Recovery Timer deleted!\n");
|
|
|
+ }
|
|
|
+
|
|
|
/* Let the USB core know _both_ roothubs lost power. */
|
|
|
usb_root_hub_lost_power(xhci->main_hcd->self.root_hub);
|
|
|
usb_root_hub_lost_power(xhci->shared_hcd->self.root_hub);
|
|
@@ -1035,6 +1043,8 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
|
|
|
retval = xhci_init(hcd->primary_hcd);
|
|
|
if (retval)
|
|
|
return retval;
|
|
|
+ comp_timer_running = true;
|
|
|
+
|
|
|
xhci_dbg(xhci, "Start the primary HCD\n");
|
|
|
retval = xhci_run(hcd->primary_hcd);
|
|
|
if (!retval) {
|
|
@@ -1076,7 +1086,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
|
|
|
* to suffer the Compliance Mode issue again. It doesn't matter if
|
|
|
* ports have entered previously to U0 before system's suspension.
|
|
|
*/
|
|
|
- if (xhci->quirks & XHCI_COMP_MODE_QUIRK)
|
|
|
+ if ((xhci->quirks & XHCI_COMP_MODE_QUIRK) && !comp_timer_running)
|
|
|
compliance_mode_recovery_timer_init(xhci);
|
|
|
|
|
|
/* Re-enable port polling. */
|