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

Reply via email to