summaryrefslogtreecommitdiff
path: root/drivers/usb/host/xhci.c
diff options
context:
space:
mode:
authorThéo Lebrun <theo.lebrun@bootlin.com>2025-02-05 18:36:52 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2025-03-14 09:18:02 +0100
commit34cca0ceab5ba34a7cfaa32bbca5eb7abb85622b (patch)
treef3c60f43ccf3b77a21c22d1a2186dd149a36aa17 /drivers/usb/host/xhci.c
parent9925aa4b025e46cffc9fc98c5fb28a4a303a739b (diff)
usb: xhci: change xhci_resume() parameters to explicit the desired info
Previous signature was: int xhci_resume(struct xhci_hcd *xhci, pm_message_t msg); Internally, it extracted two information out of the message: - whether we are after hibernation: msg.event == PM_EVENT_RESTORE, - whether this is an auto resume: msg.event == PM_EVENT_AUTO_RESUME. First bulletpoint is somewhat wrong: driver wants to know if the device did lose power, it doesn't care about hibernation per se. Knowing that, refactor to ask upper layers the right questions: (1) "did we lose power?" and, (2) "is this an auto resume?". Change the signature to: int xhci_resume(struct xhci_hcd *xhci, bool power_lost, bool is_auto_resume); The goal is to allow some upper layers (cdns3-plat) to tell us when power was lost after system-wise suspend. Note that lost_power is ORed at the start of xhci_resume() to xhci->quirks & XHCI_RESET_ON_RESUME || xhci->broken_suspend. It is simpler to keep those checks inside of xhci_resume() instead of doing them at each caller of xhci_resume(). Signed-off-by: Théo Lebrun <theo.lebrun@bootlin.com> Link: https://lore.kernel.org/r/20250205-s2r-cdns-v7-7-13658a271c3c@bootlin.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/host/xhci.c')
-rw-r--r--drivers/usb/host/xhci.c19
1 files changed, 8 insertions, 11 deletions
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 19e308f4fc06..83a4adf57bae 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -994,16 +994,14 @@ EXPORT_SYMBOL_GPL(xhci_suspend);
* This is called when the machine transition from S3/S4 mode.
*
*/
-int xhci_resume(struct xhci_hcd *xhci, pm_message_t msg)
+int xhci_resume(struct xhci_hcd *xhci, bool power_lost, bool is_auto_resume)
{
- bool hibernated = (msg.event == PM_EVENT_RESTORE);
u32 command, temp = 0;
struct usb_hcd *hcd = xhci_to_hcd(xhci);
int retval = 0;
bool comp_timer_running = false;
bool pending_portevent = false;
bool suspended_usb3_devs = false;
- bool reinit_xhc = false;
if (!hcd->state)
return 0;
@@ -1022,10 +1020,10 @@ int xhci_resume(struct xhci_hcd *xhci, pm_message_t msg)
spin_lock_irq(&xhci->lock);
- if (hibernated || xhci->quirks & XHCI_RESET_ON_RESUME || xhci->broken_suspend)
- reinit_xhc = true;
+ if (xhci->quirks & XHCI_RESET_ON_RESUME || xhci->broken_suspend)
+ power_lost = true;
- if (!reinit_xhc) {
+ if (!power_lost) {
/*
* Some controllers might lose power during suspend, so wait
* for controller not ready bit to clear, just as in xHC init.
@@ -1065,12 +1063,12 @@ int xhci_resume(struct xhci_hcd *xhci, pm_message_t msg)
/* re-initialize the HC on Restore Error, or Host Controller Error */
if ((temp & (STS_SRE | STS_HCE)) &&
!(xhci->xhc_state & XHCI_STATE_REMOVING)) {
- reinit_xhc = true;
- if (!xhci->broken_suspend)
+ if (!power_lost)
xhci_warn(xhci, "xHC error in resume, USBSTS 0x%x, Reinit\n", temp);
+ power_lost = true;
}
- if (reinit_xhc) {
+ if (power_lost) {
if ((xhci->quirks & XHCI_COMP_MODE_QUIRK) &&
!(xhci_all_ports_seen_u0(xhci))) {
del_timer_sync(&xhci->comp_mode_recovery_timer);
@@ -1168,8 +1166,7 @@ int xhci_resume(struct xhci_hcd *xhci, pm_message_t msg)
pending_portevent = xhci_pending_portevent(xhci);
- if (suspended_usb3_devs && !pending_portevent &&
- msg.event == PM_EVENT_AUTO_RESUME) {
+ if (suspended_usb3_devs && !pending_portevent && is_auto_resume) {
msleep(120);
pending_portevent = xhci_pending_portevent(xhci);
}