diff --git a/drivers/video/msm/mdss/mdss_mdp.c b/drivers/video/msm/mdss/mdss_mdp.c
index c573925f448eacaf6e675e560549607498fdecf8..c0b592e500db67657df6c32ed5b59f7dc85ca734 100644
--- a/drivers/video/msm/mdss/mdss_mdp.c
+++ b/drivers/video/msm/mdss/mdss_mdp.c
@@ -691,16 +691,22 @@ static int mdss_mdp_clk_update(u32 clk_idx, u32 enable)
 	return ret;
 }
 
-int mdss_mdp_vsync_clk_enable(int enable)
+int mdss_mdp_vsync_clk_enable(int enable, bool locked)
 {
 	int ret = 0;
 	pr_debug("clk enable=%d\n", enable);
-	mutex_lock(&mdp_clk_lock);
+
+	if (!locked)
+		mutex_lock(&mdp_clk_lock);
+
 	if (mdss_res->vsync_ena != enable) {
 		mdss_res->vsync_ena = enable;
 		ret = mdss_mdp_clk_update(MDSS_CLK_MDP_VSYNC, enable);
 	}
-	mutex_unlock(&mdp_clk_lock);
+
+	if (!locked)
+		mutex_unlock(&mdp_clk_lock);
+
 	return ret;
 }
 
@@ -733,14 +739,19 @@ void mdss_mdp_set_clk_rate(unsigned long rate)
 	}
 }
 
-unsigned long mdss_mdp_get_clk_rate(u32 clk_idx)
+unsigned long mdss_mdp_get_clk_rate(u32 clk_idx, bool locked)
 {
 	unsigned long clk_rate = 0;
 	struct clk *clk = mdss_mdp_get_clk(clk_idx);
-	mutex_lock(&mdp_clk_lock);
-	if (clk)
+	if (clk) {
+		if (!locked)
+			mutex_lock(&mdp_clk_lock);
+
 		clk_rate = clk_get_rate(clk);
-	mutex_unlock(&mdp_clk_lock);
+
+		if (!locked)
+			mutex_unlock(&mdp_clk_lock);
+	}
 
 	return clk_rate;
 }
@@ -806,7 +817,7 @@ static int mdss_mdp_idle_pc_restore(void)
 	}
 	mdss_hw_init(mdata);
 	mdss_iommu_ctrl(0);
-	mdss_mdp_ctl_restore();
+	mdss_mdp_ctl_restore(true);
 	mdata->idle_pc = false;
 
 end:
@@ -907,10 +918,10 @@ void mdss_mdp_clk_ctrl(int enable)
 		}
 	}
 
-	mutex_unlock(&mdp_clk_lock);
-
 	if (enable && changed)
 		mdss_mdp_idle_pc_restore();
+
+	mutex_unlock(&mdp_clk_lock);
 }
 
 static inline int mdss_mdp_irq_clk_register(struct mdss_data_type *mdata,
@@ -984,7 +995,7 @@ static int mdss_mdp_irq_clk_setup(struct mdss_data_type *mdata)
 	mdss_mdp_irq_clk_register(mdata, "vsync_clk", MDSS_CLK_MDP_VSYNC);
 
 	mdss_mdp_set_clk_rate(MDP_CLK_DEFAULT_RATE);
-	pr_debug("mdp clk rate=%ld\n", mdss_mdp_get_clk_rate(MDSS_CLK_MDP_SRC));
+	pr_debug("mdp clk rate=%ld\n", mdss_mdp_get_clk_rate(MDSS_CLK_MDP_SRC, false));
 
 	return 0;
 }
@@ -1150,11 +1161,9 @@ static void mdss_hw_rev_init(struct mdss_data_type *mdata)
 	if (mdata->mdp_rev)
 		return;
 
-	mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON);
 	mdata->mdp_rev = MDSS_REG_READ(mdata, MDSS_REG_HW_VERSION);
 	pr_info_once("MDP Rev=%x\n", mdata->mdp_rev);
 	mdss_mdp_hw_rev_caps_init(mdata);
-	mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF);
 }
 
 /**
@@ -1420,7 +1429,9 @@ static ssize_t mdss_mdp_show_capabilities(struct device *dev,
 #define SPRINT(fmt, ...) \
 		(cnt += scnprintf(buf + cnt, len - cnt, fmt, ##__VA_ARGS__))
 
+	mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON);
 	mdss_hw_rev_init(mdata);
+	mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF);
 
 	SPRINT("mdp_version=5\n");
 	SPRINT("hw_rev=%d\n", mdata->mdp_rev);
diff --git a/drivers/video/msm/mdss/mdss_mdp.h b/drivers/video/msm/mdss/mdss_mdp.h
index 63a388061531a1fa23f9e5dc3de10f7cb106d6f1..9b10121df4b168cca5266166c3bd041230fb1157 100644
--- a/drivers/video/msm/mdss/mdss_mdp.h
+++ b/drivers/video/msm/mdss/mdss_mdp.h
@@ -228,7 +228,7 @@ struct mdss_mdp_ctl {
 					struct mdss_mdp_vsync_handler *);
 	int (*config_fps_fnc) (struct mdss_mdp_ctl *ctl,
 				struct mdss_mdp_ctl *sctl, int new_fps);
-	int (*restore_fnc) (struct mdss_mdp_ctl *ctl);
+	int (*restore_fnc)(struct mdss_mdp_ctl *ctl, bool locked);
 
 	struct blocking_notifier_head notifier_head;
 
@@ -701,8 +701,8 @@ void mdss_mdp_footswitch_ctrl_splash(int on);
 void mdss_mdp_batfet_ctrl(struct mdss_data_type *mdata, int enable);
 int mdss_mdp_bus_scale_set_quota(u64 ab_quota, u64 ib_quota);
 void mdss_mdp_set_clk_rate(unsigned long min_clk_rate);
-unsigned long mdss_mdp_get_clk_rate(u32 clk_idx);
-int mdss_mdp_vsync_clk_enable(int enable);
+unsigned long mdss_mdp_get_clk_rate(u32 clk_idx, bool locked);
+int mdss_mdp_vsync_clk_enable(int enable, bool locked);
 void mdss_mdp_clk_ctrl(int enable);
 struct mdss_data_type *mdss_mdp_get_mdata(void);
 int mdss_mdp_secure_display_ctrl(unsigned int enable);
@@ -916,6 +916,6 @@ int mdss_mdp_wb_get_format(struct msm_fb_data_type *mfd,
 int mdss_mdp_pipe_program_pixel_extn(struct mdss_mdp_pipe *pipe);
 int mdss_mdp_wb_set_secure(struct msm_fb_data_type *mfd, int enable);
 int mdss_mdp_wb_get_secure(struct msm_fb_data_type *mfd, uint8_t *enable);
-void mdss_mdp_ctl_restore(void);
+void mdss_mdp_ctl_restore(bool locked);
 int  mdss_mdp_ctl_reset(struct mdss_mdp_ctl *ctl);
 #endif /* MDSS_MDP_H */
diff --git a/drivers/video/msm/mdss/mdss_mdp_ctl.c b/drivers/video/msm/mdss/mdss_mdp_ctl.c
index 52910d45c9c4375ad263652aa454cea6025c1f49..c5af3d79aba605200a4b937c293c1dd52679cfd9 100644
--- a/drivers/video/msm/mdss/mdss_mdp_ctl.c
+++ b/drivers/video/msm/mdss/mdss_mdp_ctl.c
@@ -1995,19 +1995,25 @@ static void mdss_mdp_ctl_restore_sub(struct mdss_mdp_ctl *ctl)
 
 /*
  * mdss_mdp_ctl_restore() - restore mdp ctl path
+ * @locked - boolean to signal that clock lock is already acquired
  *
  * This function is called whenever MDP comes out of a power collapse as
  * a result of a screen update. It restores the MDP controller's software
  * state to the hardware registers.
+ * Function does not enable the clocks, so caller must make sure
+ * clocks are enabled before calling.
+ * The locked boolean in the parametrs signals that synchronization
+ * with mdp clocks access is not required downstream.
+ * Only call this function setting this value to true if the clocks access
+ * synchronization is guaranteed by the caller.
  */
-void mdss_mdp_ctl_restore(void)
+void mdss_mdp_ctl_restore(bool locked)
 {
 	struct mdss_mdp_ctl *ctl = NULL;
 	struct mdss_mdp_ctl *sctl;
 	struct mdss_data_type *mdata = mdss_mdp_get_mdata();
 	u32 cnum;
 
-	mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON);
 	for (cnum = MDSS_MDP_CTL0; cnum < mdata->nctl; cnum++) {
 		ctl = mdata->ctl_off + cnum;
 		if (!mdss_mdp_ctl_is_power_on(ctl))
@@ -2023,9 +2029,8 @@ void mdss_mdp_ctl_restore(void)
 			mdss_mdp_ctl_split_display_enable(1, ctl, sctl);
 		}
 		if (ctl->restore_fnc)
-			ctl->restore_fnc(ctl);
+			ctl->restore_fnc(ctl, locked);
 	}
-	mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF);
 }
 
 static int mdss_mdp_ctl_start_sub(struct mdss_mdp_ctl *ctl, bool handoff)
diff --git a/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c b/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c
index cde188301ba6a2206e80fa0a24e654d9405d721e..3a58049b600457caaf942d0203cd49f4ea4be319 100644
--- a/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c
+++ b/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c
@@ -113,7 +113,7 @@ exit:
 
 
 static int mdss_mdp_cmd_tearcheck_cfg(struct mdss_mdp_ctl *ctl,
-	struct mdss_mdp_mixer *mixer, bool enable)
+	struct mdss_mdp_mixer *mixer, bool enable, bool locked)
 {
 	struct mdss_mdp_pp_tear_check *te = NULL;
 	struct mdss_panel_info *pinfo;
@@ -130,10 +130,10 @@ static int mdss_mdp_cmd_tearcheck_cfg(struct mdss_mdp_ctl *ctl,
 		pinfo = &ctl->panel_data->panel_info;
 		te = &ctl->panel_data->panel_info.te;
 
-		mdss_mdp_vsync_clk_enable(1);
+		mdss_mdp_vsync_clk_enable(1, locked);
 
 		vsync_clk_speed_hz =
-			mdss_mdp_get_clk_rate(MDSS_CLK_MDP_VSYNC);
+			mdss_mdp_get_clk_rate(MDSS_CLK_MDP_VSYNC, locked);
 
 		total_lines = mdss_panel_get_vtotal(pinfo);
 
@@ -193,14 +193,15 @@ static int mdss_mdp_cmd_tearcheck_cfg(struct mdss_mdp_ctl *ctl,
 	return 0;
 }
 
-static int mdss_mdp_cmd_tearcheck_setup(struct mdss_mdp_ctl *ctl, bool enable)
+static int mdss_mdp_cmd_tearcheck_setup(struct mdss_mdp_ctl *ctl, bool enable,
+					bool locked)
 {
 	int rc = 0;
 	struct mdss_mdp_mixer *mixer;
 
 	mixer = mdss_mdp_mixer_get(ctl, MDSS_MDP_MIXER_MUX_LEFT);
 	if (mixer) {
-		rc = mdss_mdp_cmd_tearcheck_cfg(ctl, mixer, enable);
+		rc = mdss_mdp_cmd_tearcheck_cfg(ctl, mixer, enable, locked);
 		if (rc)
 			goto err;
 	}
@@ -208,7 +209,7 @@ static int mdss_mdp_cmd_tearcheck_setup(struct mdss_mdp_ctl *ctl, bool enable)
 	if (!(ctl->opmode & MDSS_MDP_CTL_OP_PACK_3D_ENABLE)) {
 		mixer = mdss_mdp_mixer_get(ctl, MDSS_MDP_MIXER_MUX_RIGHT);
 		if (mixer)
-			rc = mdss_mdp_cmd_tearcheck_cfg(ctl, mixer, enable);
+			rc = mdss_mdp_cmd_tearcheck_cfg(ctl, mixer, enable, locked);
 	}
  err:
 	return rc;
@@ -793,13 +794,11 @@ int mdss_mdp_cmd_kickoff(struct mdss_mdp_ctl *ctl, void *arg)
 	return 0;
 }
 
-int mdss_mdp_cmd_restore(struct mdss_mdp_ctl *ctl)
+int mdss_mdp_cmd_restore(struct mdss_mdp_ctl *ctl, bool locked)
 {
 	pr_debug("%s: called for ctl%d\n", __func__, ctl->num);
-	mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON);
-	if (mdss_mdp_cmd_tearcheck_setup(ctl, true))
+	if (mdss_mdp_cmd_tearcheck_setup(ctl, true, locked))
 		pr_warn("%s: tearcheck setup failed\n", __func__);
-	mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF);
 
 	return 0;
 }
@@ -867,7 +866,7 @@ int mdss_mdp_cmd_intfs_stop(struct mdss_mdp_ctl *ctl, int session,
 
 	mdss_mdp_cmd_clk_off(ctx);
 	flush_work(&ctx->pp_done_work);
-	mdss_mdp_cmd_tearcheck_setup(ctl, false);
+	mdss_mdp_cmd_tearcheck_setup(ctl, false, false);
 
 	if (mdss_panel_is_power_on(panel_power_state)) {
 		pr_debug("%s: intf stopped with panel on\n", __func__);
@@ -1047,7 +1046,9 @@ static int mdss_mdp_cmd_intfs_setup(struct mdss_mdp_ctl *ctl,
 			 * explictly call the restore function to enable
 			 * tearcheck logic.
 			 */
-			mdss_mdp_cmd_restore(ctl);
+			mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON);
+			mdss_mdp_cmd_restore(ctl, false);
+			mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF);
 
 			/* Turn on panel so that it can exit low power mode */
 			ret = mdss_mdp_cmd_panel_on(ctl, sctl);
@@ -1099,7 +1100,7 @@ static int mdss_mdp_cmd_intfs_setup(struct mdss_mdp_ctl *ctl,
 	mdss_mdp_set_intr_callback(MDSS_MDP_IRQ_PING_PONG_COMP, ctx->pp_num,
 				   mdss_mdp_cmd_pingpong_done, ctl);
 
-	ret = mdss_mdp_cmd_tearcheck_setup(ctl, true);
+	ret = mdss_mdp_cmd_tearcheck_setup(ctl, true, true);
 	if (ret) {
 		pr_err("tearcheck setup failed\n");
 		return ret;
diff --git a/drivers/video/msm/mdss/mdss_mdp_overlay.c b/drivers/video/msm/mdss/mdss_mdp_overlay.c
index e3f2790d4d630872d4c29fc226723cef0621981d..c97bba2f421e35df0321cc1451b59b041d3be2e3 100644
--- a/drivers/video/msm/mdss/mdss_mdp_overlay.c
+++ b/drivers/video/msm/mdss/mdss_mdp_overlay.c
@@ -3621,7 +3621,7 @@ static int mdss_mdp_overlay_handoff(struct msm_fb_data_type *mfd)
 		goto error;
 	}
 
-	ctl->clk_rate = mdss_mdp_get_clk_rate(MDSS_CLK_MDP_SRC);
+	ctl->clk_rate = mdss_mdp_get_clk_rate(MDSS_CLK_MDP_SRC, false);
 	pr_debug("Set the ctl clock rate to %d Hz\n", ctl->clk_rate);
 
 	rc = __mdss_mdp_ctl_handoff(ctl, mdata);