diff options
| author | Pawan Kumar <pavaku@codeaurora.org> | 2013-12-20 12:00:11 +0530 |
|---|---|---|
| committer | David Keitel <dkeitel@codeaurora.org> | 2016-03-23 20:24:53 -0700 |
| commit | 3b620a5a4bedb51f67fc539f7e7e35cc42fb7f42 (patch) | |
| tree | 01e14147b20857661ed02992bc14ea3a284d435c /drivers/video/fbdev | |
| parent | a384604d572532a6b377f3e8e39dcb55a455629a (diff) | |
msm: mdss: Fix race condition for vsync irq enable/disable
Disable and enable of vsync happens in separate thread, which
may lead to a race condition where enable/disable may
happen at the same time and resulting irq in disable state.
Add lock to properly synchronize the enabling/disabling
of vsync interrupts to fix race condition.
Change-Id: Ib52bea5ca7a3612c866a4a962f09725a77e40563
Signed-off-by: Pawan Kumar <pavaku@codeaurora.org>
Diffstat (limited to 'drivers/video/fbdev')
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_intf_video.c | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/drivers/video/fbdev/msm/mdss_mdp_intf_video.c b/drivers/video/fbdev/msm/mdss_mdp_intf_video.c index 84643de78181..a469dead830b 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_intf_video.c +++ b/drivers/video/fbdev/msm/mdss_mdp_intf_video.c @@ -62,6 +62,7 @@ struct mdss_mdp_video_ctx { atomic_t vsync_ref; spinlock_t vsync_lock; + struct mutex vsync_mtx; struct list_head vsync_handlers; }; @@ -216,19 +217,23 @@ static inline void video_vsync_irq_enable(struct mdss_mdp_ctl *ctl, bool clear) { struct mdss_mdp_video_ctx *ctx = ctl->priv_data; + mutex_lock(&ctx->vsync_mtx); if (atomic_inc_return(&ctx->vsync_ref) == 1) mdss_mdp_irq_enable(MDSS_MDP_IRQ_INTF_VSYNC, ctl->intf_num); else if (clear) mdss_mdp_irq_clear(ctl->mdata, MDSS_MDP_IRQ_INTF_VSYNC, ctl->intf_num); + mutex_unlock(&ctx->vsync_mtx); } static inline void video_vsync_irq_disable(struct mdss_mdp_ctl *ctl) { struct mdss_mdp_video_ctx *ctx = ctl->priv_data; + mutex_lock(&ctx->vsync_mtx); if (atomic_dec_return(&ctx->vsync_ref) == 0) mdss_mdp_irq_disable(MDSS_MDP_IRQ_INTF_VSYNC, ctl->intf_num); + mutex_unlock(&ctx->vsync_mtx); } static int mdss_mdp_video_add_vsync_handler(struct mdss_mdp_ctl *ctl, @@ -687,6 +692,7 @@ int mdss_mdp_video_start(struct mdss_mdp_ctl *ctl) ctx->intf_type = ctl->intf_type; init_completion(&ctx->vsync_comp); spin_lock_init(&ctx->vsync_lock); + mutex_init(&ctx->vsync_mtx); atomic_set(&ctx->vsync_ref, 0); mdss_mdp_set_intr_callback(MDSS_MDP_IRQ_INTF_VSYNC, ctl->intf_num, |
