Re: [PATCH v2 2/7] usb: dwc3: qcom: Distinguish PM and runtime suspend/resume paths
From: Thinh Nguyen
Date: Fri Sep 11 2026 - 19:52:40 EST
On Thu, Sep 03, 2026, Faisal Hassan wrote:
> The dwc3_qcom_suspend() and dwc3_qcom_resume() functions
> handle both system PM and runtime PM paths but cannot
> differentiate between them, preventing distinct power
> management strategies.
>
> Refactor suspend/resume functions to accept pm_message_t
> instead of boolean wakeup flags. Use PMSG_IS_AUTO()
> to identify runtime PM (PMSG_AUTO_SUSPEND/RESUME) versus
> system PM (PMSG_SUSPEND/RESUME) paths.
>
> Preserve existing wakeup behavior: always enable wakeup
> for runtime suspend, check device_may_wakeup() for system
> suspend.
>
> Follow dwc3/core.c pattern to enable future per-path
> strategies like differentiated power states.
>
> Co-developed-by: Sriram Dash <sriram.dash@xxxxxxxxxxxxxxxx>
> Signed-off-by: Sriram Dash <sriram.dash@xxxxxxxxxxxxxxxx>
> Signed-off-by: Faisal Hassan <faisal.hassan@xxxxxxxxxxxxxxxx>
> ---
> drivers/usb/dwc3/dwc3-qcom.c | 34 ++++++++++++++++++++++++++--------
> 1 file changed, 26 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/usb/dwc3/dwc3-qcom.c b/drivers/usb/dwc3/dwc3-qcom.c
> index 49698a31b2f4..6d25f81800a7 100644
> --- a/drivers/usb/dwc3/dwc3-qcom.c
> +++ b/drivers/usb/dwc3/dwc3-qcom.c
> @@ -335,14 +335,24 @@ static void dwc3_qcom_enable_interrupts(struct dwc3_qcom *qcom)
> dwc3_qcom_enable_port_interrupts(&qcom->ports[i]);
> }
>
> -static int dwc3_qcom_suspend(struct dwc3_qcom *qcom, bool wakeup)
> +static int dwc3_qcom_suspend(struct dwc3_qcom *qcom, pm_message_t msg)
> {
> u32 val;
> int i, ret;
> + bool wakeup;
>
> if (qcom->is_suspended)
> return 0;
>
> + /*
> + * For runtime suspend, always enable wakeup.
> + * For system suspend, check device wakeup capability.
> + */
> + if (PMSG_IS_AUTO(msg))
> + wakeup = true;
> + else
> + wakeup = device_may_wakeup(qcom->dev);
> +
> 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))
> @@ -369,14 +379,24 @@ static int dwc3_qcom_suspend(struct dwc3_qcom *qcom, bool wakeup)
> return 0;
> }
>
> -static int dwc3_qcom_resume(struct dwc3_qcom *qcom, bool wakeup)
> +static int dwc3_qcom_resume(struct dwc3_qcom *qcom, pm_message_t msg)
> {
> int ret;
> int i;
> + bool wakeup;
>
> if (!qcom->is_suspended)
> return 0;
>
> + /*
> + * For runtime resume, always assume wakeup was enabled.
> + * For system resume, check device wakeup capability.
> + */
> + if (PMSG_IS_AUTO(msg))
> + wakeup = true;
> + else
> + wakeup = device_may_wakeup(qcom->dev);
> +
> if (dwc3_qcom_is_host(qcom) && wakeup)
> dwc3_qcom_disable_interrupts(qcom);
>
> @@ -759,14 +779,13 @@ static int dwc3_qcom_pm_suspend(struct device *dev)
> {
> struct dwc3 *dwc = dev_get_drvdata(dev);
> struct dwc3_qcom *qcom = to_dwc3_qcom(dwc);
> - bool wakeup = device_may_wakeup(dev);
> int ret;
>
> ret = dwc3_pm_suspend(&qcom->dwc);
> if (ret)
> return ret;
>
> - ret = dwc3_qcom_suspend(qcom, wakeup);
> + ret = dwc3_qcom_suspend(qcom, PMSG_SUSPEND);
> if (ret)
> return ret;
>
> @@ -779,10 +798,9 @@ static int dwc3_qcom_pm_resume(struct device *dev)
> {
> struct dwc3 *dwc = dev_get_drvdata(dev);
> struct dwc3_qcom *qcom = to_dwc3_qcom(dwc);
> - bool wakeup = device_may_wakeup(dev);
> int ret;
>
> - ret = dwc3_qcom_resume(qcom, wakeup);
> + ret = dwc3_qcom_resume(qcom, PMSG_RESUME);
> if (ret)
> return ret;
>
> @@ -819,7 +837,7 @@ static int dwc3_qcom_runtime_suspend(struct device *dev)
> if (ret)
> return ret;
>
> - return dwc3_qcom_suspend(qcom, true);
> + return dwc3_qcom_suspend(qcom, PMSG_AUTO_SUSPEND);
> }
>
> static int dwc3_qcom_runtime_resume(struct device *dev)
> @@ -828,7 +846,7 @@ static int dwc3_qcom_runtime_resume(struct device *dev)
> struct dwc3_qcom *qcom = to_dwc3_qcom(dwc);
> int ret;
>
> - ret = dwc3_qcom_resume(qcom, true);
> + ret = dwc3_qcom_resume(qcom, PMSG_AUTO_RESUME);
> if (ret)
> return ret;
>
> --
> 2.34.1
>
Acked-by: Thinh Nguyen <Thinh.Nguyen@xxxxxxxxxxxx>
Thanks,
Thinh