All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Joonhoe Kim" <26rote@gmail.com>
Cc: linux-usb@vger.kernel.org
Subject: Re: [PATCH RESEND] usb: dwc3: tell xHCI that it lost its state when the core is powered off
Date: Thu, 12 Nov 2026 12:00:08 +0000	[thread overview]
Message-ID: <sashiko-outbox-211064@kernel.org> (raw)
In-Reply-To: <20261112114053.412-1-26rote@gmail.com>

Thank you for your contribution! Sashiko AI review found 2 potential
issues to consider:
- [Medium] usb: dwc3: stale xhci_power_lost after resume in
  dwc3_xhci_resume_quirk()
- [Medium] usb: dwc3: missing xhci_power_lost set for OTG host in
  dwc3_suspend_common()
It also noticed 1 related pre-existing issue this patch does not
introduce:
- [High] usb: dwc3: missing xhci_power_lost for OTG mode in
  dwc3_suspend_common() [1]
--

commit 1536e0b07384ff8dbfd40131768e7772947697b4
Author: Joonhoe Kim <26rote@gmail.com>

usb: dwc3: tell xHCI that it lost its state when the core is powered off

This commit records when dwc3_suspend_common() powers off the DWC3 core
during host-mode system suspend and passes that state to xhci-plat as
power_lost via a resume_quirk callback.

> diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
> index fd5c2cd36c595..b5490b9a8474f 100644
> --- a/drivers/usb/dwc3/core.c
> +++ b/drivers/usb/dwc3/core.c
> @@ -2572,8 +2572,10 @@ static int dwc3_suspend_common(struct dwc3 *dwc, pm_message_t msg)
>  		if (!PMSG_IS_AUTO(msg) &&
>  		    (!device_may_wakeup(dwc->dev) || dwc->needs_full_reinit)) {
>  			dwc3_core_exit(dwc);
> +			dwc->xhci_power_lost = 1;
>  			break;
>  		}
> +		dwc->xhci_power_lost = 0;

[Severity: Medium]
Does the DWC3_GCTL_PRTCAP_OTG case in dwc3_suspend_common() also need to
set dwc->xhci_power_lost?

When the controller operates in OTG mode with the host role active
(dwc->current_otg_role == DWC3_OTG_ROLE_HOST), dwc3_otg_update() registers
the xhci-hcd device while dwc->current_dr_role stays DWC3_GCTL_PRTCAP_OTG.
On system suspend, the DWC3_GCTL_PRTCAP_OTG branch unconditionally calls
dwc3_core_exit(dwc) without setting dwc->xhci_power_lost:

drivers/usb/dwc3/core.c:dwc3_suspend_common() {
    ...
	case DWC3_GCTL_PRTCAP_OTG:
		/* do nothing during runtime_suspend */
		if (PMSG_IS_AUTO(msg))
			break;
    ...
		dwc3_otg_exit(dwc);
		dwc3_core_exit(dwc);
		break;
}

On resume, dwc3_resume_common() reinitializes the core from scratch, but
dwc3_xhci_resume_quirk() still sees xhci_power_lost == 0 and xhci_resume()
attempts to restore state onto the reset controller.

[Severity: High]
This problem wasn't introduced by this patch, but in OTG host mode
[1] does dwc3_suspend_common() power off the core via
dwc3_core_exit() without telling xhci-plat that power was lost?  When a
dual-role controller in DWC3_GCTL_PRTCAP_OTG mode is acting as host,
system suspend tears down the core in the DWC3_GCTL_PRTCAP_OTG branch while
leaving xhci_power_lost unset, so xhci_resume() tries to restore saved
registers to a reset controller and triggers unhandled IOMMU context faults
or command ring timeouts.

> diff --git a/drivers/usb/dwc3/host.c b/drivers/usb/dwc3/host.c
> index c5674161b2b08..c7143a8e3e326 100644
> --- a/drivers/usb/dwc3/host.c
> +++ b/drivers/usb/dwc3/host.c

[ ... ]

> @@ -78,7 +76,23 @@ static void dwc3_xhci_plat_start(struct usb_hcd *hcd)
>  	dwc3_enable_susphy(dwc, true);
>  }
>  
> +/*
> + * dwc3_suspend_common() powers the core off for system suspend in host mode
> + * when the controller may not wake the system. The xHCI registers and its
> + * saved internal state are gone then: tell xhci-plat, so that xhci_resume()
> + * resets the controller instead of restoring registers and asking it to
> + * restore a state it no longer has.
> + */
> +static int dwc3_xhci_resume_quirk(struct usb_hcd *hcd)
> +{
> +	struct dwc3 *dwc = dev_get_drvdata(hcd->self.controller->parent);
> +
> +	hcd_to_xhci_priv(hcd)->power_lost = dwc->xhci_power_lost;
> +	return 0;
> +}

[Severity: Medium]
Can dwc->xhci_power_lost remain 1 after resume and cause an unnecessary
xHCI reset on a later aborted suspend?

Neither dwc3_xhci_resume_quirk() nor dwc3_resume_common() clears
dwc->xhci_power_lost after a power-off suspend/resume cycle.  If a
subsequent system suspend aborts after the child xhci-hcd device runs
xhci_plat_suspend() but before the parent dwc3 device runs
dwc3_suspend_common(), dpm_resume() calls dwc3_xhci_resume_quirk(), which
reads the stale dwc->xhci_power_lost == 1 and forces xhci_resume() to reset
the controller and re-enumerate all attached devices even though the core
stayed powered.

[1] https://sashiko.dev/#/bug/linux-d6c3b577-381b-4dd2-a215-d44eec3c0bbf

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261112114053.412-1-26rote@gmail.com?part=1

  reply	other threads:[~2026-11-12 12:00 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-12 11:40 [PATCH RESEND] usb: dwc3: tell xHCI that it lost its state when the core is powered off Joonhoe Kim
2026-11-12 12:00 ` sashiko-bot [this message]
2026-11-12 14:15   ` Joonhoe Kim

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=sashiko-outbox-211064@kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=26rote@gmail.com \
    --cc=linux-usb@vger.kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.