From: Niklas Neronin <niklas.neronin@linux.intel.com>
To: mathias.nyman@linux.intel.com
Cc: linux-usb@vger.kernel.org, raoxu@uniontech.com,
Thinh.Nguyen@synopsys.com,
Niklas Neronin <niklas.neronin@linux.intel.com>
Subject: [RFC PATCH 08/12] usb: xhci: improve debug messages during suspend
Date: Thu, 5 Mar 2026 15:48:20 +0100 [thread overview]
Message-ID: <20260305144824.3264408-9-niklas.neronin@linux.intel.com> (raw)
In-Reply-To: <20260305144824.3264408-1-niklas.neronin@linux.intel.com>
Improve debug output for suspend failures, particularly when the controller
handshake does not complete. This will become important as upcoming patches
significantly rework the resume path, making more detailed suspend-side
messages valuable for debugging.
Add an explicit check of the Save/Restore Error (SRE) flag after a
successful Save State (CSS) operation. The xHCI specification
(note in section 4.23.2) states:
"After a Save or Restore State operation completes, the
Save/Restore Error (SRE) flag in USBSTS should be checked to
ensure the operation completed successfully."
Currently, the SRE error is only observed and warning is printed.
This patch does not introduce deeper error handling, as the correct
response is unclear and changes to suspend behavior may risk regressions
once the resume path is updated.
Additionally, simplify and clean up the suspend USBSTS CSS/SSS
handling code, improving readability and quirk handling for AMD
SNPS xHC controllers that occasionally do not clear the SSS bit.
Signed-off-by: Niklas Neronin <niklas.neronin@linux.intel.com>
---
drivers/usb/host/xhci.c | 65 +++++++++++++++++++++++------------------
1 file changed, 37 insertions(+), 28 deletions(-)
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 0c2239b5b805..b22f10cfbe7b 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -950,11 +950,11 @@ static bool xhci_pending_portevent(struct xhci_hcd *xhci)
*/
int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup)
{
- int rc = 0;
+ int err;
unsigned int delay = XHCI_MAX_HALT_USEC * 2;
struct usb_hcd *hcd = xhci_to_hcd(xhci);
u32 command;
- u32 res;
+ u32 usbsts;
if (!hcd->state)
return 0;
@@ -1000,11 +1000,10 @@ int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup)
/* Some chips from Fresco Logic need an extraordinary delay */
delay *= (xhci->quirks & XHCI_SLOW_SUSPEND) ? 10 : 1;
- if (xhci_handshake(&xhci->op_regs->status,
- STS_HALT, STS_HALT, delay)) {
- xhci_warn(xhci, "WARN: xHC CMD_RUN timeout\n");
- spin_unlock_irq(&xhci->lock);
- return -ETIMEDOUT;
+ err = xhci_handshake(&xhci->op_regs->status, STS_HALT, STS_HALT, delay);
+ if (err) {
+ xhci_warn(xhci, "Clearing Run/Stop bit failed %d\n", err);
+ goto handshake_error;
}
xhci_clear_command_ring(xhci);
@@ -1015,28 +1014,34 @@ int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup)
command = readl(&xhci->op_regs->command);
command |= CMD_CSS;
writel(command, &xhci->op_regs->command);
+
+ err = xhci_handshake(&xhci->op_regs->status, STS_SAVE, 0, 20 * USEC_PER_MSEC);
+ usbsts = readl(&xhci->op_regs->status);
xhci->broken_suspend = 0;
- if (xhci_handshake(&xhci->op_regs->status,
- STS_SAVE, 0, 20 * 1000)) {
- /*
- * AMD SNPS xHC 3.0 occasionally does not clear the
- * SSS bit of USBSTS and when driver tries to poll
- * to see if the xHC clears BIT(8) which never happens
- * and driver assumes that controller is not responding
- * and times out. To workaround this, its good to check
- * if SRE and HCE bits are not set (as per xhci
- * Section 5.4.2) and bypass the timeout.
- */
- res = readl(&xhci->op_regs->status);
- if ((xhci->quirks & XHCI_SNPS_BROKEN_SUSPEND) &&
- (((res & STS_SRE) == 0) &&
- ((res & STS_HCE) == 0))) {
- xhci->broken_suspend = 1;
- } else {
- xhci_warn(xhci, "WARN: xHC save state timeout\n");
- spin_unlock_irq(&xhci->lock);
- return -ETIMEDOUT;
+ if (err) {
+ /*
+ * AMD SNPS xHC 3.0 occasionally does not clear the
+ * SSS bit of USBSTS and when driver tries to poll
+ * to see if the xHC clears BIT(8) which never happens
+ * and driver assumes that controller is not responding
+ * and times out. To workaround this, its good to check
+ * if SRE and HCE bits are not set (as per xhci
+ * Section 5.4.2) and bypass the timeout.
+ */
+ if (!(xhci->quirks & XHCI_SNPS_BROKEN_SUSPEND)) {
+ xhci_warn(xhci, "Controller Save State failed %d\n", err);
+ goto handshake_error;
}
+
+ if (usbsts & (STS_SRE | STS_HCE)) {
+ xhci_warn(xhci, "Controller Save State failed, USBSTS 0x%08x\n", usbsts);
+ goto handshake_error;
+ }
+
+ xhci_dbg(xhci, "SNPS broken suspend, save state unreliable\n");
+ xhci->broken_suspend = 1;
+ } else if (usbsts & STS_SRE) {
+ xhci_warn(xhci, "Suspend Save Error (SRE), USBSTS 0x%08x\n", usbsts);
}
spin_unlock_irq(&xhci->lock);
@@ -1052,7 +1057,11 @@ int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup)
__func__);
}
- return rc;
+ return 0;
+
+handshake_error:
+ spin_unlock_irq(&xhci->lock);
+ return -ETIMEDOUT;
}
EXPORT_SYMBOL_GPL(xhci_suspend);
--
2.50.1
next prev parent reply other threads:[~2026-03-05 14:48 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-05 14:48 [RFC PATCH 00/12] usb: xhci: groundwork for secondary interrupters Niklas Neronin
2026-03-05 14:48 ` [RFC PATCH 01/12] usb: xhci: simplify CMRT initialization logic Niklas Neronin
2026-03-05 14:48 ` [RFC PATCH 02/12] usb: xhci: relocate Restore/Controller error check Niklas Neronin
2026-03-05 14:48 ` [RFC PATCH 03/12] usb: xhci: simplify USBSTS register reset Niklas Neronin
2026-03-05 19:26 ` Michal Pecio
2026-03-05 14:48 ` [RFC PATCH 04/12] usb: xhci: move reserving command ring trb Niklas Neronin
2026-03-05 14:48 ` [RFC PATCH 05/12] usb: xhci: move ring initialization Niklas Neronin
2026-03-05 14:48 ` [RFC PATCH 06/12] usb: xhci: move initialization for lifetime objects Niklas Neronin
2026-03-05 22:14 ` Michal Pecio
2026-03-06 9:47 ` Neronin, Niklas
2026-03-05 14:48 ` [RFC PATCH 07/12] usb: xhci: split core allocation and initialization Niklas Neronin
2026-03-05 22:23 ` Michal Pecio
2026-03-05 14:48 ` Niklas Neronin [this message]
2026-03-05 14:48 ` [RFC PATCH 09/12] usb: xhci: optimize resuming from S4 (suspend-to-RAM) Niklas Neronin
2026-03-06 6:52 ` raoxu
2026-03-06 10:16 ` Neronin, Niklas
2026-03-06 7:05 ` Michal Pecio
2026-03-05 14:48 ` [RFC PATCH 10/12] usb: xhci: add interrupter type Niklas Neronin
2026-03-05 14:48 ` [RFC PATCH 11/12] usb: xhci: prepare for multiple interrupters Niklas Neronin
2026-03-05 14:48 ` [RFC PATCH 12/12] usb: xhci: prepare IRQ handler " Niklas Neronin
2026-03-06 6:53 ` raoxu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260305144824.3264408-9-niklas.neronin@linux.intel.com \
--to=niklas.neronin@linux.intel.com \
--cc=Thinh.Nguyen@synopsys.com \
--cc=linux-usb@vger.kernel.org \
--cc=mathias.nyman@linux.intel.com \
--cc=raoxu@uniontech.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox