summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorBenjamin Chan <bkchan@codeaurora.org>2016-11-08 21:48:21 -0500
committerBenjamin Chan <bkchan@codeaurora.org>2016-11-10 18:24:00 -0500
commit39e8fe5924e7edeef614d049452c8b7b26f5655e (patch)
tree1bab171d0e4d0b7c61de5c7a80a4a8d2b38bb0ad /drivers
parentcd316285c5cb5f72cff8cd4e65ff6154a2ff3a4b (diff)
msm: sde: Fix SDE rotator context list locking
During rotator IRQ handling, it is possible that the context list getting updated with open and close handling within the IRQ timeframe, so it is necessary to add the spinlock to protect the context list. CRs-Fixed: 1087423 Change-Id: I20a04c766e55c75db15662e9a13e20396b35f30e Signed-off-by: Benjamin Chan <bkchan@codeaurora.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c3
-rw-r--r--drivers/media/platform/msm/sde/rotator/sde_rotator_r3_internal.h22
2 files changed, 24 insertions, 1 deletions
diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c b/drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c
index 925b8497273a..4e86a3ff820d 100644
--- a/drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c
+++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c
@@ -1502,7 +1502,8 @@ static void sde_hw_rotator_free_rotctx(struct sde_hw_rotator *rot,
ctx->q_id, ctx->timestamp,
atomic_read(&ctx->hwres->num_active));
- rot->rotCtx[ctx->q_id][sde_hw_rotator_get_regdma_ctxidx(ctx)] = NULL;
+ /* Clear rotator context from lookup purpose */
+ sde_hw_rotator_clr_ctx(ctx);
devm_kfree(&rot->pdev->dev, ctx);
}
diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_r3_internal.h b/drivers/media/platform/msm/sde/rotator/sde_rotator_r3_internal.h
index 91ac3d0371fa..7aecc3cee210 100644
--- a/drivers/media/platform/msm/sde/rotator/sde_rotator_r3_internal.h
+++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_r3_internal.h
@@ -345,10 +345,32 @@ static inline void sde_hw_rotator_put_ctx(struct sde_hw_rotator_context *ctx)
{
struct sde_hw_rotator *rot = ctx->rot;
u32 idx = sde_hw_rotator_get_regdma_ctxidx(ctx);
+ unsigned long flags;
+ spin_lock_irqsave(&rot->rotisr_lock, flags);
rot->rotCtx[ctx->q_id][idx] = ctx;
+ spin_unlock_irqrestore(&rot->rotisr_lock, flags);
+
SDEROT_DBG("rotCtx[%d][%d] <== ctx:%p | session-id:%d\n",
ctx->q_id, idx, ctx, ctx->session_id);
}
+/**
+ * sde_hw_rotator_clr_ctx(): Clearing rotator context according to its
+ * timestamp.
+ */
+static inline void sde_hw_rotator_clr_ctx(struct sde_hw_rotator_context *ctx)
+{
+ struct sde_hw_rotator *rot = ctx->rot;
+ u32 idx = sde_hw_rotator_get_regdma_ctxidx(ctx);
+ unsigned long flags;
+
+ spin_lock_irqsave(&rot->rotisr_lock, flags);
+ rot->rotCtx[ctx->q_id][idx] = NULL;
+ spin_unlock_irqrestore(&rot->rotisr_lock, flags);
+
+ SDEROT_DBG("rotCtx[%d][%d] <== null | session-id:%d\n",
+ ctx->q_id, idx, ctx->session_id);
+}
+
#endif /*_SDE_ROTATOR_R3_INTERNAL_H */