summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVeera Sundaram Sankaran <veeras@codeaurora.org>2015-09-24 12:38:21 -0700
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-23 20:46:16 -0700
commit628abdbe097bc1613416d471e5300cf0c4c6b880 (patch)
tree747eaf563c953937ea1b746a384832cfc03c41a9
parent1a66eac51e40bb9c481703b35692d65646e69524 (diff)
msm: mdss: clear irq if RD_PTR intr is detected before clk disable
Before disabling the RD_PTR ISR and turning off the clks, there is a possibility that some other CPU might have received a READ_PTR ISR few microseconds before and started to process it. By the time, the ISR reaches the register read instructions, the clks might be disabled. To avoid such cases, check for the intr status after disabling the ISR and clear the irq before disabling the clks. Change-Id: If9f0e2df22ec7ea26d62b08c9364c2047dda8c51 Signed-off-by: Veera Sundaram Sankaran <veeras@codeaurora.org>
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp.c22
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp.h1
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c7
3 files changed, 30 insertions, 0 deletions
diff --git a/drivers/video/fbdev/msm/mdss_mdp.c b/drivers/video/fbdev/msm/mdss_mdp.c
index 1585b4091e8b..aa3dc467b054 100644
--- a/drivers/video/fbdev/msm/mdss_mdp.c
+++ b/drivers/video/fbdev/msm/mdss_mdp.c
@@ -578,6 +578,28 @@ void mdss_mdp_irq_disable(u32 intr_type, u32 intf_num)
spin_unlock_irqrestore(&mdp_lock, irq_flags);
}
+/*
+ * This function is used to check and clear the status of
+ * INTR and does not handle INTR2 and HIST_INTR
+ */
+void mdss_mdp_intr_check_and_clear(u32 intr_type, u32 intf_num)
+{
+ u32 status, irq;
+ struct mdss_data_type *mdata = mdss_mdp_get_mdata();
+
+ irq = mdss_mdp_irq_mask(intr_type, intf_num);
+
+ spin_lock(&mdp_lock);
+ status = irq & readl_relaxed(mdata->mdp_base +
+ MDSS_MDP_REG_INTR_STATUS);
+ if (status) {
+ pr_debug("clearing irq: intr_type:%d, intf_num:%d\n",
+ intr_type, intf_num);
+ writel_relaxed(irq, mdata->mdp_base + MDSS_MDP_REG_INTR_CLEAR);
+ }
+ spin_unlock(&mdp_lock);
+}
+
void mdss_mdp_hist_irq_disable(u32 irq)
{
struct mdss_data_type *mdata = mdss_mdp_get_mdata();
diff --git a/drivers/video/fbdev/msm/mdss_mdp.h b/drivers/video/fbdev/msm/mdss_mdp.h
index cbfb687767a5..52108de5bd9f 100644
--- a/drivers/video/fbdev/msm/mdss_mdp.h
+++ b/drivers/video/fbdev/msm/mdss_mdp.h
@@ -982,6 +982,7 @@ void mdss_mdp_irq_clear(struct mdss_data_type *mdata,
u32 intr_type, u32 intf_num);
int mdss_mdp_irq_enable(u32 intr_type, u32 intf_num);
void mdss_mdp_irq_disable(u32 intr_type, u32 intf_num);
+void mdss_mdp_intr_check_and_clear(u32 intr_type, u32 intf_num);
int mdss_mdp_hist_irq_enable(u32 irq);
void mdss_mdp_hist_irq_disable(u32 irq);
void mdss_mdp_irq_disable_nosync(u32 intr_type, u32 intf_num);
diff --git a/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c b/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c
index 9757fc5ad2e6..8577f2806965 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c
@@ -1187,6 +1187,13 @@ static int mdss_mdp_setup_vsync(struct mdss_mdp_cmd_ctx *ctx,
/* disable clocks and irq */
mdss_mdp_irq_disable(MDSS_MDP_IRQ_PING_PONG_RD_PTR,
ctx->pp_num);
+ /*
+ * check the intr status and clear the irq before
+ * disabling the clocks
+ */
+ mdss_mdp_intr_check_and_clear(
+ MDSS_MDP_IRQ_PING_PONG_RD_PTR, ctx->pp_num);
+
mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF);
}
}