From 00804197384686bbcefb25bfb09816aac7fbbd36 Mon Sep 17 00:00:00 2001 From: Jayant Shekhar Date: Thu, 18 Dec 2014 12:59:25 +0530 Subject: [PATCH] msm: mdss: Synchronize control stop and ESD check Use ctl mutex offlock to synchronize between control stop and BTA ESD status check function to prevent any race condition. Change-Id: I841e03a066b6e9e193ba9c6deae20d5527d4a20f Signed-off-by: Jayant Shekhar --- drivers/video/fbdev/msm/dsi_status_6g.c | 12 +++++++----- drivers/video/fbdev/msm/mdss_dsi.c | 2 -- drivers/video/fbdev/msm/mdss_dsi_status.c | 5 +++-- drivers/video/fbdev/msm/mdss_mdp.h | 1 + drivers/video/fbdev/msm/mdss_mdp_ctl.c | 1 + drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c | 2 ++ drivers/video/fbdev/msm/mdss_mdp_intf_video.c | 10 ++++++---- 7 files changed, 20 insertions(+), 13 deletions(-) diff --git a/drivers/video/fbdev/msm/dsi_status_6g.c b/drivers/video/fbdev/msm/dsi_status_6g.c index b61062911580..d2c894e86cf3 100644 --- a/drivers/video/fbdev/msm/dsi_status_6g.c +++ b/drivers/video/fbdev/msm/dsi_status_6g.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -138,7 +138,6 @@ void mdss_check_dsi_ctrl_status(struct work_struct *work, uint32_t interval) return; } - mutex_lock(&ctrl_pdata->mutex); /* * TODO: Because mdss_dsi_cmd_mdp_busy has made sure DMA to @@ -147,13 +146,16 @@ void mdss_check_dsi_ctrl_status(struct work_struct *work, uint32_t interval) * lock to fix issues so that ESD thread would not block other * overlay operations. Need refine this lock for command mode */ + + mutex_lock(&ctl->offlock); if (mipi->mode == DSI_CMD_MODE) mutex_lock(&mdp5_data->ov_lock); - if (mdss_panel_is_power_off(pstatus_data->mfd->panel_power_state)) { + if (mdss_panel_is_power_off(pstatus_data->mfd->panel_power_state) || + pstatus_data->mfd->shutdown_pending) { if (mipi->mode == DSI_CMD_MODE) mutex_unlock(&mdp5_data->ov_lock); - mutex_unlock(&ctrl_pdata->mutex); + mutex_unlock(&ctl->offlock); pr_err("%s: DSI turning off, avoiding panel status check\n", __func__); return; @@ -180,7 +182,7 @@ void mdss_check_dsi_ctrl_status(struct work_struct *work, uint32_t interval) if (mipi->mode == DSI_CMD_MODE) mutex_unlock(&mdp5_data->ov_lock); - mutex_unlock(&ctrl_pdata->mutex); + mutex_unlock(&ctl->offlock); if ((pstatus_data->mfd->panel_power_state == MDSS_PANEL_POWER_ON)) { if (ret > 0) diff --git a/drivers/video/fbdev/msm/mdss_dsi.c b/drivers/video/fbdev/msm/mdss_dsi.c index 42421e0dc5ac..bc5a41ba0959 100644 --- a/drivers/video/fbdev/msm/mdss_dsi.c +++ b/drivers/video/fbdev/msm/mdss_dsi.c @@ -548,7 +548,6 @@ static int mdss_dsi_off(struct mdss_panel_data *pdata, int power_state) ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata, panel_data); - mutex_lock(&ctrl_pdata->mutex); panel_info = &ctrl_pdata->panel_data.panel_info; pr_debug("%s+: ctrl=%p ndx=%d power_state=%d\n", @@ -591,7 +590,6 @@ panel_power_ctrl: panel_info->mipi.frame_rate = panel_info->new_fps; end: - mutex_unlock(&ctrl_pdata->mutex); pr_debug("%s-:\n", __func__); return ret; diff --git a/drivers/video/fbdev/msm/mdss_dsi_status.c b/drivers/video/fbdev/msm/mdss_dsi_status.c index 7de0a49a4b95..f3bb69ea0c4e 100644 --- a/drivers/video/fbdev/msm/mdss_dsi_status.c +++ b/drivers/video/fbdev/msm/mdss_dsi_status.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -60,7 +60,8 @@ static void check_dsi_ctrl_status(struct work_struct *work) return; } - if (mdss_panel_is_power_off(pdsi_status->mfd->panel_power_state)) { + if (mdss_panel_is_power_off(pdsi_status->mfd->panel_power_state) || + pdsi_status->mfd->shutdown_pending) { pr_err("%s: panel off\n", __func__); return; } diff --git a/drivers/video/fbdev/msm/mdss_mdp.h b/drivers/video/fbdev/msm/mdss_mdp.h index 7a0dcc108c85..6d841e6d3edb 100644 --- a/drivers/video/fbdev/msm/mdss_mdp.h +++ b/drivers/video/fbdev/msm/mdss_mdp.h @@ -262,6 +262,7 @@ struct mdss_mdp_ctl { struct mdss_mdp_mixer *mixer_right; struct mdss_mdp_cdm *cdm; struct mutex lock; + struct mutex offlock; struct mutex *shared_lock; spinlock_t spin_lock; diff --git a/drivers/video/fbdev/msm/mdss_mdp_ctl.c b/drivers/video/fbdev/msm/mdss_mdp_ctl.c index 958211e83f84..2994656aa58c 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_ctl.c +++ b/drivers/video/fbdev/msm/mdss_mdp_ctl.c @@ -1697,6 +1697,7 @@ struct mdss_mdp_ctl *mdss_mdp_ctl_alloc(struct mdss_data_type *mdata, ctl->ref_cnt++; ctl->mdata = mdata; mutex_init(&ctl->lock); + mutex_init(&ctl->offlock); spin_lock_init(&ctl->spin_lock); BLOCKING_INIT_NOTIFIER_HEAD(&ctl->notifier_head); pr_debug("alloc ctl_num=%d\n", ctl->num); diff --git a/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c b/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c index ea9d94a37e09..ca08fcda3e73 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c +++ b/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c @@ -1129,6 +1129,7 @@ int mdss_mdp_cmd_stop(struct mdss_mdp_ctl *ctl, int panel_power_state) ctx->autorefresh_pending = pre_suspend; } + mutex_lock(&ctl->offlock); if (__mdss_mdp_cmd_is_panel_power_on_interactive(ctx)) { if (mdss_panel_is_power_on_lp(panel_power_state)) { /* @@ -1218,6 +1219,7 @@ end: ctx->panel_power_state = panel_power_state; MDSS_XLOG(ctl->num, atomic_read(&ctx->koff_cnt), ctx->clk_enabled, ctx->rdptr_enabled, XLOG_FUNC_EXIT); + mutex_unlock(&ctl->offlock); pr_debug("%s:-\n", __func__); return ret; diff --git a/drivers/video/fbdev/msm/mdss_mdp_intf_video.c b/drivers/video/fbdev/msm/mdss_mdp_intf_video.c index ab9cc0c50807..da79db1af662 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_intf_video.c +++ b/drivers/video/fbdev/msm/mdss_mdp_intf_video.c @@ -423,7 +423,7 @@ static int mdss_mdp_video_intfs_stop(struct mdss_mdp_ctl *ctl, struct mdss_mdp_video_ctx *ctx; struct mdss_mdp_vsync_handler *tmp, *handle; struct mdss_mdp_ctl *sctl; - int rc; + int rc = 0; u32 frame_rate = 0; int ret = 0; @@ -452,12 +452,13 @@ static int mdss_mdp_video_intfs_stop(struct mdss_mdp_ctl *ctl, return -EINVAL; } + mutex_lock(&ctl->offlock); if (ctx->timegen_en) { rc = mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_BLANK, NULL); if (rc == -EBUSY) { pr_debug("intf #%d busy don't turn off\n", ctl->intf_num); - return rc; + goto end; } WARN(rc, "intf %d blank error (%d)\n", ctl->intf_num, rc); @@ -495,8 +496,9 @@ static int mdss_mdp_video_intfs_stop(struct mdss_mdp_ctl *ctl, (inum + MDSS_MDP_INTF0), NULL, NULL); ctx->ref_cnt--; - - return 0; +end: + mutex_unlock(&ctl->offlock); + return rc; }