Merge branch 'for-linus' of git://git.samba.org/sfrench/cifs-2.6
[deliverable/linux.git] / drivers / gpu / drm / exynos / exynos_drm_fimd.c
index e488b80bef5e23f017f85c77c2786f1ac931c8dc..e5810d13bf9c5377b9faa5afc0fc333bd6d2ab17 100644 (file)
@@ -84,8 +84,6 @@
 /* FIMD has totally five hardware windows. */
 #define WINDOWS_NR     5
 
-#define get_fimd_manager(mgr)  platform_get_drvdata(to_platform_device(dev))
-
 struct fimd_driver_data {
        unsigned int timing_base;
        unsigned int lcdblk_offset;
@@ -159,6 +157,7 @@ struct fimd_win_data {
 };
 
 struct fimd_context {
+       struct exynos_drm_manager       manager;
        struct device                   *dev;
        struct drm_device               *drm_dev;
        struct clk                      *bus_clk;
@@ -186,6 +185,11 @@ struct fimd_context {
        struct exynos_drm_display *display;
 };
 
+static inline struct fimd_context *mgr_to_fimd(struct exynos_drm_manager *mgr)
+{
+       return container_of(mgr, struct fimd_context, manager);
+}
+
 static const struct of_device_id fimd_driver_dt_match[] = {
        { .compatible = "samsung,s3c6400-fimd",
          .data = &s3c64xx_fimd_driver_data },
@@ -212,7 +216,7 @@ static inline struct fimd_driver_data *drm_fimd_get_driver_data(
 
 static void fimd_wait_for_vblank(struct exynos_drm_manager *mgr)
 {
-       struct fimd_context *ctx = mgr->ctx;
+       struct fimd_context *ctx = mgr_to_fimd(mgr);
 
        if (ctx->suspended)
                return;
@@ -257,7 +261,7 @@ static void fimd_enable_shadow_channel_path(struct fimd_context *ctx, int win,
 
 static void fimd_clear_channel(struct exynos_drm_manager *mgr)
 {
-       struct fimd_context *ctx = mgr->ctx;
+       struct fimd_context *ctx = mgr_to_fimd(mgr);
        int win, ch_enabled = 0;
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
@@ -290,7 +294,7 @@ static void fimd_clear_channel(struct exynos_drm_manager *mgr)
 static int fimd_mgr_initialize(struct exynos_drm_manager *mgr,
                        struct drm_device *drm_dev)
 {
-       struct fimd_context *ctx = mgr->ctx;
+       struct fimd_context *ctx = mgr_to_fimd(mgr);
        struct exynos_drm_private *priv;
        priv = drm_dev->dev_private;
 
@@ -312,7 +316,7 @@ static int fimd_mgr_initialize(struct exynos_drm_manager *mgr,
 
 static void fimd_mgr_remove(struct exynos_drm_manager *mgr)
 {
-       struct fimd_context *ctx = mgr->ctx;
+       struct fimd_context *ctx = mgr_to_fimd(mgr);
 
        /* detach this sub driver from iommu mapping if supported. */
        if (is_drm_iommu_supported(ctx->drm_dev))
@@ -352,14 +356,14 @@ static bool fimd_mode_fixup(struct exynos_drm_manager *mgr,
 static void fimd_mode_set(struct exynos_drm_manager *mgr,
                const struct drm_display_mode *in_mode)
 {
-       struct fimd_context *ctx = mgr->ctx;
+       struct fimd_context *ctx = mgr_to_fimd(mgr);
 
        drm_mode_copy(&ctx->mode, in_mode);
 }
 
 static void fimd_commit(struct exynos_drm_manager *mgr)
 {
-       struct fimd_context *ctx = mgr->ctx;
+       struct fimd_context *ctx = mgr_to_fimd(mgr);
        struct drm_display_mode *mode = &ctx->mode;
        struct fimd_driver_data *driver_data = ctx->driver_data;
        void *timing_base = ctx->regs + driver_data->timing_base;
@@ -459,7 +463,7 @@ static void fimd_commit(struct exynos_drm_manager *mgr)
 
 static int fimd_enable_vblank(struct exynos_drm_manager *mgr)
 {
-       struct fimd_context *ctx = mgr->ctx;
+       struct fimd_context *ctx = mgr_to_fimd(mgr);
        u32 val;
 
        if (ctx->suspended)
@@ -491,7 +495,7 @@ static int fimd_enable_vblank(struct exynos_drm_manager *mgr)
 
 static void fimd_disable_vblank(struct exynos_drm_manager *mgr)
 {
-       struct fimd_context *ctx = mgr->ctx;
+       struct fimd_context *ctx = mgr_to_fimd(mgr);
        u32 val;
 
        if (ctx->suspended)
@@ -516,7 +520,7 @@ static void fimd_disable_vblank(struct exynos_drm_manager *mgr)
 static void fimd_win_mode_set(struct exynos_drm_manager *mgr,
                        struct exynos_drm_overlay *overlay)
 {
-       struct fimd_context *ctx = mgr->ctx;
+       struct fimd_context *ctx = mgr_to_fimd(mgr);
        struct fimd_win_data *win_data;
        int win;
        unsigned long offset;
@@ -674,7 +678,7 @@ static void fimd_shadow_protect_win(struct fimd_context *ctx,
 
 static void fimd_win_commit(struct exynos_drm_manager *mgr, int zpos)
 {
-       struct fimd_context *ctx = mgr->ctx;
+       struct fimd_context *ctx = mgr_to_fimd(mgr);
        struct fimd_win_data *win_data;
        int win = zpos;
        unsigned long val, alpha, size;
@@ -797,7 +801,7 @@ static void fimd_win_commit(struct exynos_drm_manager *mgr, int zpos)
 
 static void fimd_win_disable(struct exynos_drm_manager *mgr, int zpos)
 {
-       struct fimd_context *ctx = mgr->ctx;
+       struct fimd_context *ctx = mgr_to_fimd(mgr);
        struct fimd_win_data *win_data;
        int win = zpos;
 
@@ -831,7 +835,7 @@ static void fimd_win_disable(struct exynos_drm_manager *mgr, int zpos)
 
 static void fimd_window_suspend(struct exynos_drm_manager *mgr)
 {
-       struct fimd_context *ctx = mgr->ctx;
+       struct fimd_context *ctx = mgr_to_fimd(mgr);
        struct fimd_win_data *win_data;
        int i;
 
@@ -845,7 +849,7 @@ static void fimd_window_suspend(struct exynos_drm_manager *mgr)
 
 static void fimd_window_resume(struct exynos_drm_manager *mgr)
 {
-       struct fimd_context *ctx = mgr->ctx;
+       struct fimd_context *ctx = mgr_to_fimd(mgr);
        struct fimd_win_data *win_data;
        int i;
 
@@ -858,7 +862,7 @@ static void fimd_window_resume(struct exynos_drm_manager *mgr)
 
 static void fimd_apply(struct exynos_drm_manager *mgr)
 {
-       struct fimd_context *ctx = mgr->ctx;
+       struct fimd_context *ctx = mgr_to_fimd(mgr);
        struct fimd_win_data *win_data;
        int i;
 
@@ -875,7 +879,7 @@ static void fimd_apply(struct exynos_drm_manager *mgr)
 
 static int fimd_poweron(struct exynos_drm_manager *mgr)
 {
-       struct fimd_context *ctx = mgr->ctx;
+       struct fimd_context *ctx = mgr_to_fimd(mgr);
        int ret;
 
        if (!ctx->suspended)
@@ -923,7 +927,7 @@ bus_clk_err:
 
 static int fimd_poweroff(struct exynos_drm_manager *mgr)
 {
-       struct fimd_context *ctx = mgr->ctx;
+       struct fimd_context *ctx = mgr_to_fimd(mgr);
 
        if (ctx->suspended)
                return 0;
@@ -965,8 +969,7 @@ static void fimd_dpms(struct exynos_drm_manager *mgr, int mode)
 
 static void fimd_trigger(struct device *dev)
 {
-       struct exynos_drm_manager *mgr = get_fimd_manager(dev);
-       struct fimd_context *ctx = mgr->ctx;
+       struct fimd_context *ctx = dev_get_drvdata(dev);
        struct fimd_driver_data *driver_data = ctx->driver_data;
        void *timing_base = ctx->regs + driver_data->timing_base;
        u32 reg;
@@ -995,7 +998,7 @@ static void fimd_trigger(struct device *dev)
 
 static void fimd_te_handler(struct exynos_drm_manager *mgr)
 {
-       struct fimd_context *ctx = mgr->ctx;
+       struct fimd_context *ctx = mgr_to_fimd(mgr);
 
        /* Checks the crtc is detached already from encoder */
        if (ctx->pipe < 0 || !ctx->drm_dev)
@@ -1014,7 +1017,7 @@ static void fimd_te_handler(struct exynos_drm_manager *mgr)
                wake_up(&ctx->wait_vsync_queue);
        }
 
-       if (!atomic_read(&ctx->triggering))
+       if (test_bit(0, &ctx->irq_flags))
                drm_handle_vblank(ctx->drm_dev, ctx->pipe);
 }
 
@@ -1032,11 +1035,6 @@ static struct exynos_drm_manager_ops fimd_manager_ops = {
        .te_handler = fimd_te_handler,
 };
 
-static struct exynos_drm_manager fimd_manager = {
-       .type = EXYNOS_DISPLAY_TYPE_LCD,
-       .ops = &fimd_manager_ops,
-};
-
 static irqreturn_t fimd_irq_handler(int irq, void *dev_id)
 {
        struct fimd_context *ctx = (struct fimd_context *)dev_id;
@@ -1052,13 +1050,15 @@ static irqreturn_t fimd_irq_handler(int irq, void *dev_id)
        if (ctx->pipe < 0 || !ctx->drm_dev)
                goto out;
 
-       drm_handle_vblank(ctx->drm_dev, ctx->pipe);
-       exynos_drm_crtc_finish_pageflip(ctx->drm_dev, ctx->pipe);
-
        if (ctx->i80_if) {
+               exynos_drm_crtc_finish_pageflip(ctx->drm_dev, ctx->pipe);
+
                /* Exits triggering mode */
                atomic_set(&ctx->triggering, 0);
        } else {
+               drm_handle_vblank(ctx->drm_dev, ctx->pipe);
+               exynos_drm_crtc_finish_pageflip(ctx->drm_dev, ctx->pipe);
+
                /* set wait vsync event to zero and wake up queue. */
                if (atomic_read(&ctx->wait_vsync_event)) {
                        atomic_set(&ctx->wait_vsync_event, 0);
@@ -1072,11 +1072,11 @@ out:
 
 static int fimd_bind(struct device *dev, struct device *master, void *data)
 {
-       struct fimd_context *ctx = fimd_manager.ctx;
+       struct fimd_context *ctx = dev_get_drvdata(dev);
        struct drm_device *drm_dev = data;
 
-       fimd_mgr_initialize(&fimd_manager, drm_dev);
-       exynos_drm_crtc_create(&fimd_manager);
+       fimd_mgr_initialize(&ctx->manager, drm_dev);
+       exynos_drm_crtc_create(&ctx->manager);
        if (ctx->display)
                exynos_drm_create_enc_conn(drm_dev, ctx->display);
 
@@ -1087,15 +1087,14 @@ static int fimd_bind(struct device *dev, struct device *master, void *data)
 static void fimd_unbind(struct device *dev, struct device *master,
                        void *data)
 {
-       struct exynos_drm_manager *mgr = dev_get_drvdata(dev);
-       struct fimd_context *ctx = fimd_manager.ctx;
+       struct fimd_context *ctx = dev_get_drvdata(dev);
 
-       fimd_dpms(mgr, DRM_MODE_DPMS_OFF);
+       fimd_dpms(&ctx->manager, DRM_MODE_DPMS_OFF);
 
        if (ctx->display)
-               exynos_dpi_remove(dev);
+               exynos_dpi_remove(ctx->display);
 
-       fimd_mgr_remove(mgr);
+       fimd_mgr_remove(&ctx->manager);
 }
 
 static const struct component_ops fimd_component_ops = {
@@ -1111,21 +1110,20 @@ static int fimd_probe(struct platform_device *pdev)
        struct resource *res;
        int ret = -EINVAL;
 
-       ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC,
-                                       fimd_manager.type);
-       if (ret)
-               return ret;
-
-       if (!dev->of_node) {
-               ret = -ENODEV;
-               goto err_del_component;
-       }
+       if (!dev->of_node)
+               return -ENODEV;
 
        ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
-       if (!ctx) {
-               ret = -ENOMEM;
-               goto err_del_component;
-       }
+       if (!ctx)
+               return -ENOMEM;
+
+       ctx->manager.type = EXYNOS_DISPLAY_TYPE_LCD;
+       ctx->manager.ops = &fimd_manager_ops;
+
+       ret = exynos_drm_component_add(dev, EXYNOS_DEVICE_TYPE_CRTC,
+                                      ctx->manager.type);
+       if (ret)
+               return ret;
 
        ctx->dev = dev;
        ctx->suspended = true;
@@ -1214,27 +1212,27 @@ static int fimd_probe(struct platform_device *pdev)
        init_waitqueue_head(&ctx->wait_vsync_queue);
        atomic_set(&ctx->wait_vsync_event, 0);
 
-       platform_set_drvdata(pdev, &fimd_manager);
-
-       fimd_manager.ctx = ctx;
+       platform_set_drvdata(pdev, ctx);
 
        ctx->display = exynos_dpi_probe(dev);
-       if (IS_ERR(ctx->display))
-               return PTR_ERR(ctx->display);
+       if (IS_ERR(ctx->display)) {
+               ret = PTR_ERR(ctx->display);
+               goto err_del_component;
+       }
 
-       pm_runtime_enable(&pdev->dev);
+       pm_runtime_enable(dev);
 
-       ret = component_add(&pdev->dev, &fimd_component_ops);
+       ret = component_add(dev, &fimd_component_ops);
        if (ret)
                goto err_disable_pm_runtime;
 
        return ret;
 
 err_disable_pm_runtime:
-       pm_runtime_disable(&pdev->dev);
+       pm_runtime_disable(dev);
 
 err_del_component:
-       exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC);
+       exynos_drm_component_del(dev, EXYNOS_DEVICE_TYPE_CRTC);
        return ret;
 }
 
This page took 0.03837 seconds and 5 git commands to generate.