* [PATCH] usb: musb: Drop the D+ pullup during system suspend
@ 2026-09-27 16:41 Nguyen Minh Tien
2026-09-30 13:40 ` Andreas Kemnade
0 siblings, 1 reply; 2+ messages in thread
From: Nguyen Minh Tien @ 2026-09-27 16:41 UTC (permalink / raw)
To: Bin Liu, Greg Kroah-Hartman
Cc: Johan Hovold, Andreas Kemnade, Paul Cercueil, linux-usb,
linux-kernel, stable
When musb_suspend() clears DEVCTL, the host sees a disconnect. But VBUS
is still there, so the controller can start a new session on its own
and, with SOFTCONN still set, pull D+ up again while its interrupts are
masked. The host then fails to enumerate the gadget ("unable to
enumerate USB device") and gives up, and nothing at resume makes it try
again. On a T113-S3 board the gadget link never survived an s2idle
cycle.
Clear SOFTCONN once the context is saved; musb_restore_context() puts
it back on resume. This is what the FIXME asked for, as USB can't wake
us in time with the interrupts masked. On da8xx, which keeps the
session over suspend, the gadget now disconnects too.
Fixes: 6fc6f4b87cb3 ("usb: musb: Disable interrupts on suspend, enable them on resume")
Cc: stable@vger.kernel.org
Signed-off-by: Nguyen Minh Tien <tien.nguyenminh@embeddedlinux.blog>
---
I found this on a T113-S3 board (sunxi, s2idle, Intel xHCI host): ssh
over the gadget never came back after a suspend. With the patch, all 30
cycles I ran re-enumerated after resume.
To check for regressions, I also tried a BeagleBone Black (AM335x,
dsps glue, suspend to RAM). There the link came back after every
resume (10 cycles without the patch, 30 with it), probably because
am335x_phy_suspend() powers the PHY off.
drivers/usb/musb/musb_core.c | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index 73ac25f536..272683f14d 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -2825,18 +2825,24 @@ static int musb_suspend(struct device *dev)
spin_lock_irqsave(&musb->lock, flags);
+ musb_save_context(musb);
+
if (is_peripheral_active(musb)) {
- /* FIXME force disconnect unless we know USB will wake
- * the system up quickly enough to respond ...
+ /*
+ * We can't answer a host with the interrupts off, so drop the
+ * D+ pullup. musb_restore_context() puts back the state saved
+ * above.
*/
+ u8 power = musb_readb(musb->mregs, MUSB_POWER);
+
+ musb_writeb(musb->mregs, MUSB_POWER,
+ power & ~MUSB_POWER_SOFTCONN);
} else if (is_host_active(musb)) {
/* we know all the children are suspended; sometimes
* they will even be wakeup-enabled.
*/
}
- musb_save_context(musb);
-
spin_unlock_irqrestore(&musb->lock, flags);
return 0;
}
base-commit: 165768bb70265b5c38cf0b73fafd75be235f8b14
--
2.34.1
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [PATCH] usb: musb: Drop the D+ pullup during system suspend
2026-09-27 16:41 [PATCH] usb: musb: Drop the D+ pullup during system suspend Nguyen Minh Tien
@ 2026-09-30 13:40 ` Andreas Kemnade
0 siblings, 0 replies; 2+ messages in thread
From: Andreas Kemnade @ 2026-09-30 13:40 UTC (permalink / raw)
To: Nguyen Minh Tien
Cc: Bin Liu, Greg Kroah-Hartman, Johan Hovold, Paul Cercueil,
linux-usb, linux-kernel, stable
On Sun, 27 Sep 2026 23:41:45 +0700
Nguyen Minh Tien <tien.nguyenminh@embeddedlinux.blog> wrote:
> When musb_suspend() clears DEVCTL, the host sees a disconnect. But VBUS
> is still there, so the controller can start a new session on its own
> and, with SOFTCONN still set, pull D+ up again while its interrupts are
> masked. The host then fails to enumerate the gadget ("unable to
> enumerate USB device") and gives up, and nothing at resume makes it try
> again. On a T113-S3 board the gadget link never survived an s2idle
> cycle.
>
> Clear SOFTCONN once the context is saved; musb_restore_context() puts
> it back on resume. This is what the FIXME asked for, as USB can't wake
> us in time with the interrupts masked. On da8xx, which keeps the
> session over suspend, the gadget now disconnects too.
>
> Fixes: 6fc6f4b87cb3 ("usb: musb: Disable interrupts on suspend, enable them on resume")
> Cc: stable@vger.kernel.org
> Signed-off-by: Nguyen Minh Tien <tien.nguyenminh@embeddedlinux.blog>
> ---
> I found this on a T113-S3 board (sunxi, s2idle, Intel xHCI host): ssh
> over the gadget never came back after a suspend. With the patch, all 30
> cycles I ran re-enumerated after resume.
>
> To check for regressions, I also tried a BeagleBone Black (AM335x,
> dsps glue, suspend to RAM). There the link came back after every
> resume (10 cycles without the patch, 30 with it), probably because
> am335x_phy_suspend() powers the PHY off.
Yes, other glue layers power off the phy, too. so this issue becomes
undiscovered. I think that difference should be commented in the code
so that everybody touching this is aware of the difference.
Regards,
Andreas
>
> drivers/usb/musb/musb_core.c | 14 ++++++++++----
> 1 file changed, 10 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
> index 73ac25f536..272683f14d 100644
> --- a/drivers/usb/musb/musb_core.c
> +++ b/drivers/usb/musb/musb_core.c
> @@ -2825,18 +2825,24 @@ static int musb_suspend(struct device *dev)
>
> spin_lock_irqsave(&musb->lock, flags);
>
> + musb_save_context(musb);
> +
> if (is_peripheral_active(musb)) {
> - /* FIXME force disconnect unless we know USB will wake
> - * the system up quickly enough to respond ...
> + /*
> + * We can't answer a host with the interrupts off, so drop the
> + * D+ pullup. musb_restore_context() puts back the state saved
> + * above.
> */
> + u8 power = musb_readb(musb->mregs, MUSB_POWER);
> +
> + musb_writeb(musb->mregs, MUSB_POWER,
> + power & ~MUSB_POWER_SOFTCONN);
> } else if (is_host_active(musb)) {
> /* we know all the children are suspended; sometimes
> * they will even be wakeup-enabled.
> */
> }
>
> - musb_save_context(musb);
> -
> spin_unlock_irqrestore(&musb->lock, flags);
> return 0;
> }
>
> base-commit: 165768bb70265b5c38cf0b73fafd75be235f8b14
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-09-30 13:40 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-27 16:41 [PATCH] usb: musb: Drop the D+ pullup during system suspend Nguyen Minh Tien
2026-09-30 13:40 ` Andreas Kemnade
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®