summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMathias Nyman <mathias.nyman@linux.intel.com>2024-06-27 17:55:23 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2024-07-03 16:02:33 +0200
commit79989bd4ab86404743953fa382af0a22900050cf (patch)
tree5c9061a41ba1ca6464904f6ee2fe9451c758aa6d
parent35c41b93afb5dbefe2088402f7ec36a99c3fcf7a (diff)
xhci: always resume roothubs if xHC was reset during resume
Usb device connect may not be detected after runtime resume if xHC is reset during resume. In runtime resume cases xhci_resume() will only resume roothubs if there are pending port events. If the xHC host is reset during runtime resume due to a Save/Restore Error (SRE) then these pending port events won't be detected as PORTSC change bits are not immediately set by host after reset. Unconditionally resume roothubs if xHC is reset during resume to ensure device connections are detected. Also return early with error code if starting xHC fails after reset. Issue was debugged and a similar solution suggested by Remi Pommarel. Using this instead as it simplifies future refactoring. Reported-by: Remi Pommarel <repk@triplefau.lt> Closes: https://bugzilla.kernel.org/show_bug.cgi?id=218987 Suggested-by: Remi Pommarel <repk@triplefau.lt> Tested-by: Remi Pommarel <repk@triplefau.lt> Cc: stable@vger.kernel.org Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com> Link: https://lore.kernel.org/r/20240627145523.1453155-2-mathias.nyman@linux.intel.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/usb/host/xhci.c16
1 files changed, 13 insertions, 3 deletions
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 37eb37b0affa..0a8cf6c17f82 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