Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e6b8fc0d authored by Pawan Kumar's avatar Pawan Kumar
Browse files

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: default avatarPawan Kumar <pavaku@codeaurora.org>
parent e1a9092b
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -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,