summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLoic Poulain <loic.poulain@oss.qualcomm.com>2026-07-22 15:45:17 +0200
committerVinod Koul <vkoul@kernel.org>2026-08-07 11:44:09 +0530
commita9b9feb37bfa684f495e3a3553342191d2b30eee (patch)
tree41899b7440ad15494d93d7203783c7bf92919d21
parent8e3687f7e18fe84372e86875709d56c37e7525a8 (diff)
downloadlinux-a9b9feb37bfa684f495e3a3553342191d2b30eee.tar.gz
linux-a9b9feb37bfa684f495e3a3553342191d2b30eee.zip
phy: qcom: qmp-usb-legacy: Prevent unnecessary PM runtime suspend at boot
Runtime PM has to be enabled before creating the PHY, since phy_create() only enables runtime PM on the PHY device if it is already enabled on this parent device. This opens a small window where the device can be runtime suspended after pm_runtime_enable() and before the later pm_runtime_forbid(), causing an unnecessary suspend/resume cycle while the PHY is not yet registered. Take a runtime PM usage reference with pm_runtime_get_noresume() before enabling runtime PM and release it once the PHY has been created to prevent the device from being runtime suspended during that window. This also makes the probe path safe independently of pm_runtime_forbid(), which is a good preparation for potentially dropping the forbid() call in the future and letting runtime PM be enabled by default. Reviewed-by: Abel Vesa <abel.vesa@oss.qualcomm.com> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> Signed-off-by: Loic Poulain <loic.poulain@oss.qualcomm.com> Link: https://patch.msgid.link/20260722-qcom-usb-phy-fix-null-v6-4-534f7e61b9a6@oss.qualcomm.com Signed-off-by: Vinod Koul <vkoul@kernel.org>
-rw-r--r--drivers/phy/qualcomm/phy-qcom-qmp-usb-legacy.c24
1 files changed, 19 insertions, 5 deletions
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usb-legacy.c b/drivers/phy/qualcomm/phy-qcom-qmp-usb-legacy.c
index fc490589c8e4..c5160cb89207 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-usb-legacy.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-usb-legacy.c
@@ -1285,10 +1285,16 @@ static int qmp_usb_legacy_probe(struct platform_device *pdev)
if (ret)
goto err_node_put;
+ /*
+ * Enable runtime PM before creating the PHY, phy_create() only enables
+ * it on the PHY device if already enabled on the parent. Hold a usage
+ * reference so callbacks cannot run before qmp->phy is assigned.
+ */
+ pm_runtime_get_noresume(dev);
pm_runtime_set_active(dev);
ret = devm_pm_runtime_enable(dev);
if (ret)
- goto err_node_put;
+ goto err_pm_put;
/*
* Prevent runtime pm from being ON by default. Users can enable
* it using power/control in sysfs.
@@ -1297,23 +1303,31 @@ static int qmp_usb_legacy_probe(struct platform_device *pdev)
ret = phy_pipe_clk_register(qmp, np);
if (ret)
- goto err_node_put;
+ goto err_pm_put;
qmp->phy = devm_phy_create(dev, np, &qmp_usb_legacy_phy_ops);
if (IS_ERR(qmp->phy)) {
ret = PTR_ERR(qmp->phy);
dev_err(dev, "failed to create PHY: %d\n", ret);
- goto err_node_put;
+ goto err_pm_put;
}
phy_set_drvdata(qmp->phy, qmp);
+ phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+ if (IS_ERR(phy_provider)) {
+ ret = PTR_ERR(phy_provider);
+ goto err_pm_put;
+ }
+
of_node_put(np);
- phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+ pm_runtime_put(dev);
- return PTR_ERR_OR_ZERO(phy_provider);
+ return 0;
+err_pm_put:
+ pm_runtime_put_noidle(dev);
err_node_put:
of_node_put(np);
return ret;