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 <jshekhar@codeaurora.org>
This commit is contained in:
Jayant Shekhar 2014-12-18 12:59:25 +05:30 committed by David Keitel
parent bb8ed54586
commit 0080419738
7 changed files with 20 additions and 13 deletions

View file

@ -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)

View file

@ -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;

View file

@ -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;
}

View file

@ -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;

View file

@ -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);

View file

@ -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;

View file

@ -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;
}