drm/msm/dpu: Add mutex lock in control vblank irq
[linux-2.6-microblaze.git] / drivers / gpu / drm / msm / disp / dpu1 / dpu_encoder_phys_vid.c
index 2b4e5b5..d0f56c5 100644 (file)
@@ -366,7 +366,8 @@ static int dpu_encoder_phys_vid_control_vblank_irq(
        int ret = 0;
        int refcount;
 
-       refcount = atomic_read(&phys_enc->vblank_refcount);
+       mutex_lock(&phys_enc->vblank_ctl_lock);
+       refcount = phys_enc->vblank_refcount;
 
        /* Slave encoders don't report vblank */
        if (!dpu_encoder_phys_vid_is_master(phys_enc))
@@ -379,18 +380,26 @@ static int dpu_encoder_phys_vid_control_vblank_irq(
        }
 
        DRM_DEBUG_VBL("id:%u enable=%d/%d\n", DRMID(phys_enc->parent), enable,
-                     atomic_read(&phys_enc->vblank_refcount));
+                     refcount);
 
-       if (enable && atomic_inc_return(&phys_enc->vblank_refcount) == 1)
-               ret = dpu_core_irq_register_callback(phys_enc->dpu_kms,
-                               phys_enc->irq[INTR_IDX_VSYNC],
-                               dpu_encoder_phys_vid_vblank_irq,
-                               phys_enc);
-       else if (!enable && atomic_dec_return(&phys_enc->vblank_refcount) == 0)
-               ret = dpu_core_irq_unregister_callback(phys_enc->dpu_kms,
-                               phys_enc->irq[INTR_IDX_VSYNC]);
+       if (enable) {
+               if (phys_enc->vblank_refcount == 0)
+                       ret = dpu_core_irq_register_callback(phys_enc->dpu_kms,
+                                       phys_enc->irq[INTR_IDX_VSYNC],
+                                       dpu_encoder_phys_vid_vblank_irq,
+                                       phys_enc);
+               if (!ret)
+                       phys_enc->vblank_refcount++;
+       } else if (!enable) {
+               if (phys_enc->vblank_refcount == 1)
+                       ret = dpu_core_irq_unregister_callback(phys_enc->dpu_kms,
+                                       phys_enc->irq[INTR_IDX_VSYNC]);
+               if (!ret)
+                       phys_enc->vblank_refcount--;
+       }
 
 end:
+       mutex_unlock(&phys_enc->vblank_ctl_lock);
        if (ret) {
                DRM_ERROR("failed: id:%u intf:%d ret:%d enable:%d refcnt:%d\n",
                          DRMID(phys_enc->parent),
@@ -614,7 +623,7 @@ static void dpu_encoder_phys_vid_irq_control(struct dpu_encoder_phys *phys_enc,
        trace_dpu_enc_phys_vid_irq_ctrl(DRMID(phys_enc->parent),
                            phys_enc->hw_intf->idx - INTF_0,
                            enable,
-                           atomic_read(&phys_enc->vblank_refcount));
+                          phys_enc->vblank_refcount);
 
        if (enable) {
                ret = dpu_encoder_phys_vid_control_vblank_irq(phys_enc, true);
@@ -707,6 +716,8 @@ struct dpu_encoder_phys *dpu_encoder_phys_vid_init(struct drm_device *dev,
        DPU_DEBUG_VIDENC(phys_enc, "\n");
 
        dpu_encoder_phys_init(phys_enc, p);
+       mutex_init(&phys_enc->vblank_ctl_lock);
+       phys_enc->vblank_refcount = 0;
 
        dpu_encoder_phys_vid_init_ops(&phys_enc->ops);
        phys_enc->intf_mode = INTF_MODE_VIDEO;