msm: mdss: Lock post processing register writes

Ensure that post processing changes are committed and flushed independently
of other pipe commits. Workaround for hardware bug in MDSS flush
functionality.

Change-Id: I8cc2f044242c978159074040b766db8dca3a42a5
Signed-off-by: Carl Vanderlip <carlv@codeaurora.org>
Signed-off-by: Adrian Salido-Moreno <adrianm@codeaurora.org>
diff --git a/drivers/video/msm/mdss/mdss_mdp.h b/drivers/video/msm/mdss/mdss_mdp.h
index 3a1c4a8..cc7ccd3 100644
--- a/drivers/video/msm/mdss/mdss_mdp.h
+++ b/drivers/video/msm/mdss/mdss_mdp.h
@@ -348,6 +348,7 @@
 int mdss_mdp_pp_resume(u32 mixer_num);
 
 int mdss_mdp_pp_setup(struct mdss_mdp_ctl *ctl);
+int mdss_mdp_pp_setup_locked(struct mdss_mdp_ctl *ctl);
 int mdss_mdp_pipe_pp_setup(struct mdss_mdp_pipe *pipe, u32 *op);
 int mdss_mdp_pipe_sspp_setup(struct mdss_mdp_pipe *pipe, u32 *op);
 void mdss_mdp_pipe_sspp_term(struct mdss_mdp_pipe *pipe);
diff --git a/drivers/video/msm/mdss/mdss_mdp_ctl.c b/drivers/video/msm/mdss/mdss_mdp_ctl.c
index 063d922..b528d1c 100644
--- a/drivers/video/msm/mdss/mdss_mdp_ctl.c
+++ b/drivers/video/msm/mdss/mdss_mdp_ctl.c
@@ -1226,10 +1226,10 @@
 	}
 
 	/* postprocessing setup, including dspp */
-	mdss_mdp_pp_setup(ctl);
+	mdss_mdp_pp_setup_locked(ctl);
 	mdss_mdp_ctl_write(ctl, MDSS_MDP_REG_CTL_FLUSH, ctl->flush_bits);
 	if (sctl) {
-		mdss_mdp_pp_setup(sctl);
+		mdss_mdp_pp_setup_locked(sctl);
 		mdss_mdp_ctl_write(sctl, MDSS_MDP_REG_CTL_FLUSH,
 			sctl->flush_bits);
 	}
diff --git a/drivers/video/msm/mdss/mdss_mdp_pp.c b/drivers/video/msm/mdss/mdss_mdp_pp.c
index ee48f31..2320e76 100644
--- a/drivers/video/msm/mdss/mdss_mdp_pp.c
+++ b/drivers/video/msm/mdss/mdss_mdp_pp.c
@@ -740,6 +740,27 @@
 
 int mdss_mdp_pp_setup(struct mdss_mdp_ctl *ctl)
 {
+	int ret = 0;
+
+	if ((!ctl->mfd) || (!mdss_pp_res))
+		return -EINVAL;
+
+	/* TODO: have some sort of reader/writer lock to prevent unclocked
+	 * access while display power is toggled */
+	if (!ctl->mfd->panel_power_on) {
+		ret = -EPERM;
+		goto error;
+	}
+	mutex_lock(&ctl->mfd->lock);
+	ret = mdss_mdp_pp_setup_locked(ctl);
+	mutex_unlock(&ctl->mfd->lock);
+error:
+	return ret;
+}
+
+/* call only when holding and mfd->lock */
+int mdss_mdp_pp_setup_locked(struct mdss_mdp_ctl *ctl)
+{
 	u32 disp_num;
 	if ((!ctl->mfd) || (!mdss_pp_res))
 		return -EINVAL;