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:
parent
bb8ed54586
commit
0080419738
7 changed files with 20 additions and 13 deletions
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue