From: Gustavo Padovan <gustavo.pado...@collabora.co.uk>

Let pm_runtime handle the enabling/disabling of the device with proper
refcnt instead of rely on specific flags to track the enabled state.

Signed-off-by: Gustavo Padovan <gustavo.pado...@collabora.co.uk>
Signed-off-by: Inki Dae <inki....@samsung.com>
---
 drivers/gpu/drm/exynos/exynos_mixer.c | 125 +++++++++++++++++-----------------
 1 file changed, 61 insertions(+), 64 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c 
b/drivers/gpu/drm/exynos/exynos_mixer.c
index d09f8f9..7498c6e 100644
--- a/drivers/gpu/drm/exynos/exynos_mixer.c
+++ b/drivers/gpu/drm/exynos/exynos_mixer.c
@@ -70,7 +70,6 @@ enum mixer_version_id {
 };
 
 enum mixer_flag_bits {
-       MXR_BIT_POWERED,
        MXR_BIT_VSYNC,
 };
 
@@ -926,8 +925,6 @@ static int mixer_enable_vblank(struct exynos_drm_crtc *crtc)
        struct mixer_resources *res = &mixer_ctx->mixer_res;
 
        __set_bit(MXR_BIT_VSYNC, &mixer_ctx->flags);
-       if (!test_bit(MXR_BIT_POWERED, &mixer_ctx->flags))
-               return 0;
 
        /* enable vsync interrupt */
        mixer_reg_writemask(res, MXR_INT_STATUS, ~0, MXR_INT_CLEAR_VSYNC);
@@ -943,9 +940,6 @@ static void mixer_disable_vblank(struct exynos_drm_crtc 
*crtc)
 
        __clear_bit(MXR_BIT_VSYNC, &mixer_ctx->flags);
 
-       if (!test_bit(MXR_BIT_POWERED, &mixer_ctx->flags))
-               return;
-
        /* disable vsync interrupt */
        mixer_reg_writemask(res, MXR_INT_STATUS, ~0, MXR_INT_CLEAR_VSYNC);
        mixer_reg_writemask(res, MXR_INT_EN, 0, MXR_INT_EN_VSYNC);
@@ -958,9 +952,6 @@ static void mixer_update_plane(struct exynos_drm_crtc *crtc,
 
        DRM_DEBUG_KMS("win: %d\n", plane->zpos);
 
-       if (!test_bit(MXR_BIT_POWERED, &mixer_ctx->flags))
-               return;
-
        if (plane->zpos > 1 && mixer_ctx->vp_enabled)
                vp_video_buffer(mixer_ctx, plane);
        else
@@ -976,9 +967,6 @@ static void mixer_disable_plane(struct exynos_drm_crtc 
*crtc,
 
        DRM_DEBUG_KMS("win: %d\n", plane->zpos);
 
-       if (!test_bit(MXR_BIT_POWERED, &mixer_ctx->flags))
-               return;
-
        spin_lock_irqsave(&res->reg_slock, flags);
        mixer_vsync_set_update(mixer_ctx, false);
 
@@ -993,9 +981,6 @@ static void mixer_wait_for_vblank(struct exynos_drm_crtc 
*crtc)
        struct mixer_context *mixer_ctx = crtc->ctx;
        int err;
 
-       if (!test_bit(MXR_BIT_POWERED, &mixer_ctx->flags))
-               return;
-
        err = drm_vblank_get(mixer_ctx->drm_dev, mixer_ctx->pipe);
        if (err < 0) {
                DRM_DEBUG_KMS("failed to acquire vblank counter\n");
@@ -1020,43 +1005,9 @@ static void mixer_enable(struct exynos_drm_crtc *crtc)
 {
        struct mixer_context *ctx = crtc->ctx;
        struct mixer_resources *res = &ctx->mixer_res;
-       int ret;
-
-       if (test_bit(MXR_BIT_POWERED, &ctx->flags))
-               return;
 
        pm_runtime_get_sync(ctx->dev);
 
-       ret = clk_prepare_enable(res->mixer);
-       if (ret < 0) {
-               DRM_ERROR("Failed to prepare_enable the mixer clk [%d]\n", ret);
-               return;
-       }
-       ret = clk_prepare_enable(res->hdmi);
-       if (ret < 0) {
-               DRM_ERROR("Failed to prepare_enable the hdmi clk [%d]\n", ret);
-               return;
-       }
-       if (ctx->vp_enabled) {
-               ret = clk_prepare_enable(res->vp);
-               if (ret < 0) {
-                       DRM_ERROR("Failed to prepare_enable the vp clk [%d]\n",
-                                 ret);
-                       return;
-               }
-               if (ctx->has_sclk) {
-                       ret = clk_prepare_enable(res->sclk_mixer);
-                       if (ret < 0) {
-                               DRM_ERROR("Failed to prepare_enable the " \
-                                          "sclk_mixer clk [%d]\n",
-                                         ret);
-                               return;
-                       }
-               }
-       }
-
-       set_bit(MXR_BIT_POWERED, &ctx->flags);
-
        mixer_reg_writemask(res, MXR_STATUS, ~0, MXR_STATUS_SOFT_RESET);
 
        if (test_bit(MXR_BIT_VSYNC, &ctx->flags)) {
@@ -1069,29 +1020,15 @@ static void mixer_enable(struct exynos_drm_crtc *crtc)
 static void mixer_disable(struct exynos_drm_crtc *crtc)
 {
        struct mixer_context *ctx = crtc->ctx;
-       struct mixer_resources *res = &ctx->mixer_res;
        int i;
 
-       if (!test_bit(MXR_BIT_POWERED, &ctx->flags))
-               return;
-
        mixer_stop(ctx);
        mixer_regs_dump(ctx);
 
        for (i = 0; i < MIXER_WIN_NR; i++)
                mixer_disable_plane(crtc, &ctx->planes[i]);
 
-       clear_bit(MXR_BIT_POWERED, &ctx->flags);
-
-       clk_disable_unprepare(res->hdmi);
-       clk_disable_unprepare(res->mixer);
-       if (ctx->vp_enabled) {
-               clk_disable_unprepare(res->vp);
-               if (ctx->has_sclk)
-                       clk_disable_unprepare(res->sclk_mixer);
-       }
-
-       pm_runtime_put_sync(ctx->dev);
+       pm_runtime_put(ctx->dev);
 }
 
 /* Only valid for Mixer version 16.0.33.0 */
@@ -1293,10 +1230,70 @@ static int mixer_remove(struct platform_device *pdev)
        return 0;
 }
 
+#ifdef CONFIG_PM_SLEEP
+static int exynos_mixer_suspend(struct device *dev)
+{
+       struct mixer_context *ctx = dev_get_drvdata(dev);
+       struct mixer_resources *res = &ctx->mixer_res;
+
+       clk_disable_unprepare(res->hdmi);
+       clk_disable_unprepare(res->mixer);
+       if (ctx->vp_enabled) {
+               clk_disable_unprepare(res->vp);
+               if (ctx->has_sclk)
+                       clk_disable_unprepare(res->sclk_mixer);
+       }
+
+       return 0;
+}
+
+static int exynos_mixer_resume(struct device *dev)
+{
+       struct mixer_context *ctx = dev_get_drvdata(dev);
+       struct mixer_resources *res = &ctx->mixer_res;
+       int ret;
+
+       ret = clk_prepare_enable(res->mixer);
+       if (ret < 0) {
+               DRM_ERROR("Failed to prepare_enable the mixer clk [%d]\n", ret);
+               return ret;
+       }
+       ret = clk_prepare_enable(res->hdmi);
+       if (ret < 0) {
+               DRM_ERROR("Failed to prepare_enable the hdmi clk [%d]\n", ret);
+               return ret;
+       }
+       if (ctx->vp_enabled) {
+               ret = clk_prepare_enable(res->vp);
+               if (ret < 0) {
+                       DRM_ERROR("Failed to prepare_enable the vp clk [%d]\n",
+                                 ret);
+                       return ret;
+               }
+               if (ctx->has_sclk) {
+                       ret = clk_prepare_enable(res->sclk_mixer);
+                       if (ret < 0) {
+                               DRM_ERROR("Failed to prepare_enable the " \
+                                          "sclk_mixer clk [%d]\n",
+                                         ret);
+                               return ret;
+                       }
+               }
+       }
+
+       return 0;
+}
+#endif
+
+static const struct dev_pm_ops exynos_mixer_pm_ops = {
+       SET_RUNTIME_PM_OPS(exynos_mixer_suspend, exynos_mixer_resume, NULL)
+};
+
 struct platform_driver mixer_driver = {
        .driver = {
                .name = "exynos-mixer",
                .owner = THIS_MODULE,
+               .pm = &exynos_mixer_pm_ops,
                .of_match_table = mixer_match_types,
        },
        .probe = mixer_probe,
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to