disp: msm: cancel all delayed_works before triggering msm_lastclose
This patch cancels all the delayed_off_works if scheduled and flushes the display threads for completion during msm_lastclose. The commit from msm_lastclose client modeset to disable any crtcs if enabled is always scheduled on primary crtc_commit thread. In the current issue, delayed_off_work is scheduled on secondary display crtc_commit thread and primary crtc_commit thread is scheduled to turn off active crtcs from msm_lastclose leading to null dereference access of sde_enc's cur_master. This race is avoided by serializing the operations in msm_lastclose. Change-Id: I30cc95b925c8134f0064816ebe2cfdb86a49fb36 Signed-off-by: Jayaprakash Madisetty <quic_jmadiset@quicinc.com>
This commit is contained in:

committed by
Veera Sundaram Sankaran

szülő
50420e8d17
commit
182aac6040
@@ -2655,6 +2655,11 @@ error:
|
||||
drm_framebuffer_put(fb);
|
||||
}
|
||||
|
||||
drm_for_each_crtc(crtc, dev) {
|
||||
if (!ret && crtc_mask & drm_crtc_mask(crtc))
|
||||
sde_kms_cancel_delayed_work(crtc);
|
||||
}
|
||||
|
||||
end:
|
||||
return ret;
|
||||
}
|
||||
@@ -3881,6 +3886,7 @@ static int sde_kms_trigger_null_flush(struct msm_kms *kms)
|
||||
{
|
||||
struct sde_kms *sde_kms;
|
||||
struct sde_splash_display *splash_display;
|
||||
struct drm_crtc *crtc;
|
||||
int i, rc = 0;
|
||||
|
||||
if (!kms) {
|
||||
@@ -3898,10 +3904,14 @@ static int sde_kms_trigger_null_flush(struct msm_kms *kms)
|
||||
splash_display = &sde_kms->splash_data.splash_display[i];
|
||||
|
||||
if (splash_display->cont_splash_enabled && splash_display->encoder) {
|
||||
crtc = splash_display->encoder->crtc;
|
||||
SDE_DEBUG("triggering null commit on enc:%d\n",
|
||||
DRMID(splash_display->encoder));
|
||||
SDE_EVT32(DRMID(splash_display->encoder), SDE_EVTLOG_FUNC_ENTRY);
|
||||
rc = _sde_kms_null_commit(sde_kms->dev, splash_display->encoder);
|
||||
|
||||
if (!rc && crtc)
|
||||
sde_kms_cancel_delayed_work(crtc);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3911,7 +3921,7 @@ static int sde_kms_trigger_null_flush(struct msm_kms *kms)
|
||||
static void _sde_kms_pm_suspend_idle_helper(struct sde_kms *sde_kms,
|
||||
struct device *dev)
|
||||
{
|
||||
int i, ret, crtc_id = 0;
|
||||
int ret, crtc_id = 0;
|
||||
struct drm_device *ddev = dev_get_drvdata(dev);
|
||||
struct drm_connector *conn;
|
||||
struct drm_connector_list_iter conn_iter;
|
||||
@@ -3948,15 +3958,7 @@ static void _sde_kms_pm_suspend_idle_helper(struct sde_kms *sde_kms,
|
||||
}
|
||||
drm_connector_list_iter_end(&conn_iter);
|
||||
|
||||
for (i = 0; i < priv->num_crtcs; i++) {
|
||||
if (priv->disp_thread[i].thread)
|
||||
kthread_flush_worker(
|
||||
&priv->disp_thread[i].worker);
|
||||
if (priv->event_thread[i].thread)
|
||||
kthread_flush_worker(
|
||||
&priv->event_thread[i].worker);
|
||||
}
|
||||
kthread_flush_worker(&priv->pp_event_worker);
|
||||
msm_atomic_flush_display_threads(priv);
|
||||
}
|
||||
|
||||
struct msm_display_mode *sde_kms_get_msm_mode(struct drm_connector_state *conn_state)
|
||||
|
Reference in New Issue
Block a user