From 2c8339239f921b0ff719d76ad314b0decda1eb7b Mon Sep 17 00:00:00 2001 From: Mahadevan P Date: Thu, 17 Sep 2026 18:51:34 +0530 Subject: [PATCH] WORKAROUND: phy: qcom: qmp-combo: Request synced GDSC power-off on PHY exit On Glymur the USB PHY GDSC needs to stay powered on while the PHY is runtime suspended, so that host-mode bus suspend can resume without losing PHY state. Losing that state causes memory loss and SMMU faults, which show up as an xHCI crash on resume. The GDSC side of this is handled by the gdsc_synced_poweroff_disable callback, which only powers a GDSC off when GenPD's synced_poweroff flag is set. Add the consumer half here: once the common PHY block is fully exited and the PHY no longer needs its state preserved, call dev_pm_genpd_synced_poweroff() so the GDSC is allowed to power off instead of being retained indefinitely. Gate this on a new use_synced_poweroff config flag and enable it only for Glymur, leaving other platforms unchanged. Signed-off-by: Mahadevan P --- drivers/phy/qualcomm/phy-qcom-qmp-combo.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c index cdcfad2e86b1d..b8d9eb32653d4 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -2262,6 +2263,12 @@ struct qmp_phy_cfg { unsigned int pcs_usb_offset; bool invert_cc_polarity; + + /* + * true, if the PHY GDSC must be kept on until the common PHY block + * is fully exited, and powered off via a synced power-off request + */ + bool use_synced_poweroff; }; struct qmp_combo { @@ -3027,6 +3034,8 @@ static const struct qmp_phy_cfg glymur_usb3dpphy_cfg = { .num_resets = ARRAY_SIZE(msm8996_usb3phy_reset_l), .vreg_list = qmp_phy_vreg_refgen, .num_vregs = ARRAY_SIZE(qmp_phy_vreg_refgen), + + .use_synced_poweroff = true, }; static int qmp_combo_dp_serdes_init(struct qmp_combo *qmp) @@ -3775,6 +3784,15 @@ static int qmp_combo_com_exit(struct qmp_combo *qmp, bool force) if (!force && --qmp->init_count) return 0; + /* + * The PHY GDSC is kept on across runtime suspend so that host-mode bus + * suspend can resume without losing PHY state. Now that the common PHY + * block is fully exited, request a synced power-off to let the GDSC + * actually power down. + */ + if (cfg->use_synced_poweroff) + dev_pm_genpd_synced_poweroff(qmp->dev); + reset_control_bulk_assert(cfg->num_resets, qmp->resets); clk_disable_unprepare(qmp->pipe_clk);