Re: [PATCH] usb: dwc3: qcom: Check for L2 only when suspending a host with wakeup
From: Thinh Nguyen
Date: Fri Oct 02 2026 - 19:56:15 EST
On Mon, Sep 28, 2026, Fabricio Akio via B4 Relay wrote:
> From: Fabricio Akio <fabricioakio@xxxxxxxxx>
>
> In peripheral mode the core disconnects and powers the PHY off before
> the glue suspends, so the link never enters L2 and every system
> suspend logs "HS-PHY not in L2". Check only for a host with wakeup,
> the one case that parks the PHY in L2.
>
> Signed-off-by: Fabricio Akio <fabricioakio@xxxxxxxxx>
> ---
> Tested on a Motorola Moto X4 (XT1900-6, SDM630) with the sdm660-mainline
> 7.2.3 tree, in peripheral mode with the cable attached: the "HS-PHY not
> in L2" message appears on every system suspend without this patch, and
> not over three consecutive cycles with it. Host mode is untested, since
> this board runs the controller in peripheral mode. The board binds
> dwc3-qcom-legacy, so the same change in dwc3-qcom.c is build-tested
> only. Applies unchanged to next-20260928.
> ---
> drivers/usb/dwc3/dwc3-qcom-legacy.c | 16 ++++++++++++----
> drivers/usb/dwc3/dwc3-qcom.c | 16 ++++++++++++----
> 2 files changed, 24 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/usb/dwc3/dwc3-qcom-legacy.c b/drivers/usb/dwc3/dwc3-qcom-legacy.c
> index d3fad0fcfdac..ba3f70dea4ab 100644
> --- a/drivers/usb/dwc3/dwc3-qcom-legacy.c
> +++ b/drivers/usb/dwc3/dwc3-qcom-legacy.c
> @@ -431,10 +431,18 @@ static int dwc3_qcom_suspend(struct dwc3_qcom *qcom, bool wakeup)
> if (qcom->is_suspended)
> return 0;
>
> - for (i = 0; i < qcom->num_ports; i++) {
> - val = readl(qcom->qscratch_base + pwr_evnt_irq_stat_reg[i]);
> - if (!(val & PWR_EVNT_LPM_IN_L2_MASK))
> - dev_err(qcom->dev, "port-%d HS-PHY not in L2\n", i + 1);
> + /*
> + * Only a host with wakeup enabled keeps the HS PHY powered and parks
> + * it in L2 across suspend. A peripheral disconnects from the bus and
> + * powers the PHY off first, so its link never enters L2.
> + */
> + if (dwc3_qcom_is_host(qcom) && wakeup) {
> + for (i = 0; i < qcom->num_ports; i++) {
> + val = readl(qcom->qscratch_base + pwr_evnt_irq_stat_reg[i]);
> + if (!(val & PWR_EVNT_LPM_IN_L2_MASK))
> + dev_err(qcom->dev, "port-%d HS-PHY not in L2\n",
> + i + 1);
> + }
> }
>
> for (i = qcom->num_clocks - 1; i >= 0; i--)
> diff --git a/drivers/usb/dwc3/dwc3-qcom.c b/drivers/usb/dwc3/dwc3-qcom.c
> index ac68b4218b56..e0920da280ce 100644
> --- a/drivers/usb/dwc3/dwc3-qcom.c
> +++ b/drivers/usb/dwc3/dwc3-qcom.c
> @@ -343,10 +343,18 @@ static int dwc3_qcom_suspend(struct dwc3_qcom *qcom, bool wakeup)
> if (qcom->is_suspended)
> return 0;
>
> - for (i = 0; i < qcom->num_ports; i++) {
> - val = readl(qcom->qscratch_base + pwr_evnt_irq_stat_reg[i]);
> - if (!(val & PWR_EVNT_LPM_IN_L2_MASK))
> - dev_err(qcom->dev, "port-%d HS-PHY not in L2\n", i + 1);
> + /*
> + * Only a host with wakeup enabled keeps the HS PHY powered and parks
> + * it in L2 across suspend. A peripheral disconnects from the bus and
> + * powers the PHY off first, so its link never enters L2.
> + */
> + if (dwc3_qcom_is_host(qcom) && wakeup) {
> + for (i = 0; i < qcom->num_ports; i++) {
> + val = readl(qcom->qscratch_base + pwr_evnt_irq_stat_reg[i]);
> + if (!(val & PWR_EVNT_LPM_IN_L2_MASK))
> + dev_err(qcom->dev, "port-%d HS-PHY not in L2\n",
> + i + 1);
> + }
> }
> clk_bulk_disable_unprepare(qcom->num_clocks, qcom->clks);
>
>
> ---
> base-commit: 6375e61c01e93e35ee7acd336a689ac1fae4b509
> change-id: 20260928-dwc3-qcom-l2-check-e3b55acefb62
>
> Best regards,
> --
> Fabricio Akio <fabricioakio@xxxxxxxxx>
>
>
Acked-by: Thinh Nguyen <Thinh.Nguyen@xxxxxxxxxxxx>
Thanks,
Thinh