If msm_hdmi_phy_resource_enable() fails, e.g. when enabling regulators, it should reverse the state of things already changed. msm_hdmi_phy_resource_enable() is used also in probe path, thus such failure, which could be simple deferred probe, would leave these resources permanently enabled for the rest of the runtime.
Cc: <[email protected]> Fixes: 15b4a4523859 ("drm/msm/hdmi: Create a separate HDMI PHY driver") Signed-off-by: Krzysztof Kozlowski <[email protected]> --- drivers/gpu/drm/msm/hdmi/hdmi_phy.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_phy.c b/drivers/gpu/drm/msm/hdmi/hdmi_phy.c index eb1088755cb3..15e37596bdb1 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi_phy.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi_phy.c @@ -67,16 +67,28 @@ int msm_hdmi_phy_resource_enable(struct hdmi_phy *phy) ret = regulator_bulk_enable(cfg->num_regs, phy->regs); if (ret) { DRM_DEV_ERROR(dev, "failed to enable regulators: (%d)\n", ret); - return ret; + goto err_pm_put; } for (i = 0; i < cfg->num_clks; i++) { ret = clk_prepare_enable(phy->clks[i]); - if (ret) + if (ret) { DRM_DEV_ERROR(dev, "failed to enable clock: %s (%d)\n", cfg->clk_names[i], ret); + goto err_clk_unprepare; + } } + return 0; + +err_clk_unprepare: + for (; i > 0; i--) + clk_disable_unprepare(phy->clks[i - 1]); + regulator_bulk_disable(cfg->num_regs, phy->regs); + +err_pm_put: + pm_runtime_put_sync(dev); + return ret; } -- 2.53.0
