diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usb.c b/drivers/phy/qualcomm/phy-qcom-qmp-usb.c index bb905c437a01..b0790bcf0bc8 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-usb.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp-usb.c @@ -2419,10 +2419,16 @@ static int qmp_usb_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. @@ -2431,23 +2437,31 @@ static int qmp_usb_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_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;