public inbox for linux-usb@vger.kernel.org
 help / color / mirror / Atom feed
From: Mathias Nyman <mathias.nyman@linux.intel.com>
To: <gregkh@linuxfoundation.org>
Cc: <linux-usb@vger.kernel.org>,
	Niklas Neronin <niklas.neronin@linux.intel.com>,
	Mathias Nyman <mathias.nyman@linux.intel.com>
Subject: [PATCH 11/25] usb: xhci: improve debug messages during suspend
Date: Thu,  2 Apr 2026 16:13:28 +0300	[thread overview]
Message-ID: <20260402131342.2628648-12-mathias.nyman@linux.intel.com> (raw)
In-Reply-To: <20260402131342.2628648-1-mathias.nyman@linux.intel.com>

From: Niklas Neronin <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>
Signed-off-by: Mathias Nyman <mathias.nyman@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 9e2e2c2ed0e0..2c573aad4464 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -957,11 +957,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;
@@ -1007,11 +1007,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);
 
@@ -1022,28 +1021,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);
 
@@ -1059,7 +1064,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.43.0


  parent reply	other threads:[~2026-04-02 13:17 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-04-02 13:13 [PATCH 00/25] xhci features for usb-next Mathias Nyman
2026-04-02 13:13 ` [PATCH 01/25] xhci: use BIT macro Mathias Nyman
2026-04-02 13:13 ` [PATCH 02/25] usb: xhci: Simplify clearing the Event Interrupt bit Mathias Nyman
2026-04-02 13:13 ` [PATCH 03/25] usb: xhci: Fix debugfs bandwidth reporting Mathias Nyman
2026-04-02 13:13 ` [PATCH 04/25] usb: xhci: simplify CMRT initialization logic Mathias Nyman
2026-04-02 13:13 ` [PATCH 05/25] usb: xhci: relocate Restore/Controller error check Mathias Nyman
2026-04-02 13:13 ` [PATCH 06/25] usb: xhci: factor out roothub bandwidth cleanup Mathias Nyman
2026-04-02 13:13 ` [PATCH 07/25] usb: xhci: move reserving command ring trb Mathias Nyman
2026-04-02 13:13 ` [PATCH 08/25] usb: xhci: move ring initialization Mathias Nyman
2026-04-02 13:13 ` [PATCH 09/25] usb: xhci: move initialization for lifetime objects Mathias Nyman
2026-04-02 13:13 ` [PATCH 10/25] usb: xhci: split core allocation and initialization Mathias Nyman
2026-04-02 13:13 ` Mathias Nyman [this message]
2026-04-02 13:13 ` [PATCH 12/25] usb: xhci: optimize resuming from S4 (suspend-to-disk) Mathias Nyman
2026-04-02 13:13 ` [PATCH 13/25] usb: xhci: stop treating 'wIndex' as a mutable port number Mathias Nyman
2026-04-02 13:13 ` [PATCH 14/25] usb: xhci: rename 'wIndex' parameters to 'portnum' Mathias Nyman
2026-04-02 13:13 ` [PATCH 15/25] usb: xhci: clean up handling of upper bits in SetPortFeature wIndex Mathias Nyman
2026-04-02 13:13 ` [PATCH 16/25] usb: xhci: clean up 'wValue' handling in xhci_hub_control() Mathias Nyman
2026-04-02 13:13 ` [PATCH 17/25] usb: xhci: separate use of USB Chapter 11 PLS macros from xHCI-specific PLS macros Mathias Nyman
2026-04-02 13:13 ` [PATCH 18/25] usb: xhci: add PORTPMSC variable to xhci_hub_control() Mathias Nyman
2026-04-02 13:13 ` [PATCH 19/25] usb: xhci: add PORTSC " Mathias Nyman
2026-04-02 13:13 ` [PATCH 20/25] usb: xhci: rename parameter to match argument 'portsc' Mathias Nyman
2026-04-02 13:13 ` [PATCH 21/25] usb: xhci: cleanup xhci_hub_report_usb3_link_state() Mathias Nyman
2026-04-02 13:13 ` [PATCH 22/25] usb: xhci: simpilfy resume root hub code Mathias Nyman
2026-04-02 13:13 ` [PATCH 23/25] usb: xhci: move roothub port limit validation Mathias Nyman
2026-04-02 13:13 ` [PATCH 24/25] usb: xhci: remove duplicate '0x' prefix Mathias Nyman
2026-04-02 13:13 ` [PATCH 25/25] usb: xhci: Make usb_host_endpoint.hcpriv survive endpoint_disable() Mathias Nyman
2026-04-11 14:41 ` Question on follow-up work for secondary interrupters 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=20260402131342.2628648-12-mathias.nyman@linux.intel.com \
    --to=mathias.nyman@linux.intel.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=niklas.neronin@linux.intel.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