struct regulator *vdd;
 
+       struct clk *ahb_clk;
+       struct clk *axi_clk;
+       struct clk *vsync_clk;
+
        struct {
                volatile unsigned long enabled_mask;
                struct irq_domain *domain;
        return 0;
 }
 
+int msm_mdss_enable(struct msm_mdss *mdss)
+{
+       DBG("");
+
+       clk_prepare_enable(mdss->ahb_clk);
+       if (mdss->axi_clk)
+               clk_prepare_enable(mdss->axi_clk);
+       if (mdss->vsync_clk)
+               clk_prepare_enable(mdss->vsync_clk);
+
+       return 0;
+}
+
+int msm_mdss_disable(struct msm_mdss *mdss)
+{
+       DBG("");
+
+       if (mdss->vsync_clk)
+               clk_disable_unprepare(mdss->vsync_clk);
+       if (mdss->axi_clk)
+               clk_disable_unprepare(mdss->axi_clk);
+       clk_disable_unprepare(mdss->ahb_clk);
+
+       return 0;
+}
+
+static int msm_mdss_get_clocks(struct msm_mdss *mdss)
+{
+       struct platform_device *pdev = to_platform_device(mdss->dev->dev);
+
+       mdss->ahb_clk = msm_clk_get(pdev, "iface");
+       if (IS_ERR(mdss->ahb_clk))
+               mdss->ahb_clk = NULL;
+
+       mdss->axi_clk = msm_clk_get(pdev, "bus");
+       if (IS_ERR(mdss->axi_clk))
+               mdss->axi_clk = NULL;
+
+       mdss->vsync_clk = msm_clk_get(pdev, "vsync");
+       if (IS_ERR(mdss->vsync_clk))
+               mdss->vsync_clk = NULL;
+
+       return 0;
+}
+
 void msm_mdss_destroy(struct drm_device *dev)
 {
        struct msm_drm_private *priv = dev->dev_private;
 
        regulator_disable(mdss->vdd);
 
-       pm_runtime_put_sync(dev->dev);
-
        pm_runtime_disable(dev->dev);
 }
 
                goto fail;
        }
 
+       ret = msm_mdss_get_clocks(mdss);
+       if (ret) {
+               dev_err(dev->dev, "failed to get clocks: %d\n", ret);
+               goto fail;
+       }
+
        /* Regulator to enable GDSCs in downstream kernels */
        mdss->vdd = devm_regulator_get(dev->dev, "vdd");
        if (IS_ERR(mdss->vdd)) {
 
        pm_runtime_enable(dev->dev);
 
-       /*
-        * TODO: This is needed as the MDSS GDSC is only tied to MDSS's power
-        * domain. Remove this once runtime PM is adapted for all the devices.
-        */
-       pm_runtime_get_sync(dev->dev);
-
        return 0;
 fail_irq:
        regulator_disable(mdss->vdd);
 
 }
 #endif
 
+#ifdef CONFIG_PM
+static int msm_runtime_suspend(struct device *dev)
+{
+       struct drm_device *ddev = dev_get_drvdata(dev);
+       struct msm_drm_private *priv = ddev->dev_private;
+
+       DBG("");
+
+       if (priv->mdss)
+               return msm_mdss_disable(priv->mdss);
+
+       return 0;
+}
+
+static int msm_runtime_resume(struct device *dev)
+{
+       struct drm_device *ddev = dev_get_drvdata(dev);
+       struct msm_drm_private *priv = ddev->dev_private;
+
+       DBG("");
+
+       if (priv->mdss)
+               return msm_mdss_enable(priv->mdss);
+
+       return 0;
+}
+#endif
+
 static const struct dev_pm_ops msm_pm_ops = {
        SET_SYSTEM_SLEEP_PM_OPS(msm_pm_suspend, msm_pm_resume)
+       SET_RUNTIME_PM_OPS(msm_runtime_suspend, msm_runtime_resume, NULL)
 };
 
 /*