From 8a660b69f1b27b67e6f3f0eced78a28f56f80f67 Mon Sep 17 00:00:00 2001 From: Sandeep Panda Date: Fri, 4 May 2018 10:56:59 +0530 Subject: [PATCH] drm/msm/dsi-staging: update ESD thread disable sequence Currently to synchronize ESD check and DSI disable, ESD thread acquires display mutex before the check starts. But this is causing performance issues when atomic check also tries to acquire the display mutex and blocks on ESD thread if the later has already acquired it. Fix this race condition by removing display mutex lock from ESD thread and instead synchronize ESD check and DSI disable by always ensuring that ESD check has been stopped before DSI disable sequence kicks in. Change-Id: I5a0b44a7cbf01648303eb85c7a08a6a62c1ef94e Signed-off-by: Sandeep Panda Signed-off-by: Shashank Babu Chinta Venkata --- drivers/gpu/drm/msm/dsi-staging/dsi_display.c | 19 +++++++------------ drivers/gpu/drm/msm/sde/sde_connector.c | 3 +++ drivers/gpu/drm/msm/sde/sde_encoder.c | 5 ----- 3 files changed, 10 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_display.c b/drivers/gpu/drm/msm/dsi-staging/dsi_display.c index 916377359afe..80aed687b99a 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_display.c +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_display.c @@ -555,9 +555,6 @@ static int dsi_display_read_status(struct dsi_display_ctrl *ctrl, if (dsi_ctrl_validate_host_state(ctrl->ctrl)) return 1; - /* acquire panel_lock to make sure no commands are in progress */ - dsi_panel_acquire_panel_lock(panel); - config = &(panel->esd_config); lenp = config->status_valid_params ?: config->status_cmds_rlen; count = config->status_cmd.count; @@ -575,7 +572,7 @@ static int dsi_display_read_status(struct dsi_display_ctrl *ctrl, rc = dsi_ctrl_cmd_transfer(ctrl->ctrl, &cmds[i].msg, flags); if (rc <= 0) { pr_err("rx cmd transfer failed rc=%d\n", rc); - goto error; + return rc; } memcpy(config->return_buf + start, @@ -583,9 +580,6 @@ static int dsi_display_read_status(struct dsi_display_ctrl *ctrl, start += lenp[i]; } -error: - /* release panel_lock */ - dsi_panel_release_panel_lock(panel); return rc; } @@ -705,15 +699,16 @@ int dsi_display_check_status(struct drm_connector *connector, void *display, u32 status_mode; int rc = 0x1; - if (dsi_display == NULL) + if (!dsi_display || !dsi_display->panel) return -EINVAL; - mutex_lock(&dsi_display->display_lock); - panel = dsi_display->panel; + + dsi_panel_acquire_panel_lock(panel); + if (!panel->panel_initialized) { pr_debug("Panel not initialized\n"); - mutex_unlock(&dsi_display->display_lock); + dsi_panel_release_panel_lock(panel); return rc; } @@ -738,7 +733,7 @@ int dsi_display_check_status(struct drm_connector *connector, void *display, dsi_display_clk_ctrl(dsi_display->dsi_clk_handle, DSI_ALL_CLKS, DSI_CLK_OFF); - mutex_unlock(&dsi_display->display_lock); + dsi_panel_release_panel_lock(panel); return rc; } diff --git a/drivers/gpu/drm/msm/sde/sde_connector.c b/drivers/gpu/drm/msm/sde/sde_connector.c index 69654e762906..7433aedac66c 100644 --- a/drivers/gpu/drm/msm/sde/sde_connector.c +++ b/drivers/gpu/drm/msm/sde/sde_connector.c @@ -655,6 +655,9 @@ void sde_connector_helper_bridge_disable(struct drm_connector *connector) SDE_EVT32(connector->base.id, SDE_EVTLOG_ERROR); } + /* Disable ESD thread */ + sde_connector_schedule_status_work(connector, false); + c_conn = to_sde_connector(connector); if (c_conn->panel_dead) { c_conn->bl_device->props.power = FB_BLANK_POWERDOWN; diff --git a/drivers/gpu/drm/msm/sde/sde_encoder.c b/drivers/gpu/drm/msm/sde/sde_encoder.c index 1c262d40e86b..22301ec30fff 100644 --- a/drivers/gpu/drm/msm/sde/sde_encoder.c +++ b/drivers/gpu/drm/msm/sde/sde_encoder.c @@ -3002,7 +3002,6 @@ static void sde_encoder_virt_disable(struct drm_encoder *drm_enc) struct sde_encoder_virt *sde_enc = NULL; struct msm_drm_private *priv; struct sde_kms *sde_kms; - struct drm_connector *drm_conn = NULL; enum sde_intf_mode intf_mode; int i = 0; @@ -3031,10 +3030,6 @@ static void sde_encoder_virt_disable(struct drm_encoder *drm_enc) SDE_EVT32(DRMID(drm_enc)); - /* Disable ESD thread */ - drm_conn = sde_enc->cur_master->connector; - sde_connector_schedule_status_work(drm_conn, false); - /* wait for idle */ sde_encoder_wait_for_event(drm_enc, MSM_ENC_TX_COMPLETE);