[PATCH 3/3] drm/tilcdc: Add mutex to protect crtc enable and disable routines

Jyri Sarha jsarha at ti.com
Tue Sep 6 08:19:41 UTC 2016


Add mutex to protect crtc enable and disable routines. The
tilcdc_crtc_disable() function waits for frame done interrupt, the
internal data will get out of sync, should another enable arrive while
waiting for the interrupt.

Signed-off-by: Jyri Sarha <jsarha at ti.com>
---
 drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
index f9e3da9..ac0a63e 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
@@ -31,6 +31,7 @@ struct tilcdc_crtc {
 	const struct tilcdc_panel_info *info;
 	struct drm_pending_vblank_event *event;
 	bool enabled;
+	struct mutex enable_lock;
 	wait_queue_head_t frame_done_wq;
 	bool frame_done;
 	spinlock_t irq_lock;
@@ -153,8 +154,10 @@ static void tilcdc_crtc_enable(struct drm_crtc *crtc)
 	struct drm_device *dev = crtc->dev;
 	struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc);
 
+	mutex_lock(&tilcdc_crtc->enable_lock);
+
 	if (tilcdc_crtc->enabled)
-		return;
+		goto out;
 
 	pm_runtime_get_sync(dev->dev);
 
@@ -169,6 +172,8 @@ static void tilcdc_crtc_enable(struct drm_crtc *crtc)
 	drm_crtc_vblank_on(crtc);
 
 	tilcdc_crtc->enabled = true;
+out:
+	mutex_unlock(&tilcdc_crtc->enable_lock);
 }
 
 void tilcdc_crtc_disable(struct drm_crtc *crtc)
@@ -177,8 +182,10 @@ void tilcdc_crtc_disable(struct drm_crtc *crtc)
 	struct drm_device *dev = crtc->dev;
 	struct tilcdc_drm_private *priv = dev->dev_private;
 
+	mutex_lock(&tilcdc_crtc->enable_lock);
+
 	if (!tilcdc_crtc->enabled)
-		return;
+		goto out;
 
 	tilcdc_crtc->frame_done = false;
 	tilcdc_clear(dev, LCDC_RASTER_CTRL_REG, LCDC_RASTER_ENABLE);
@@ -218,6 +225,8 @@ void tilcdc_crtc_disable(struct drm_crtc *crtc)
 	tilcdc_crtc->last_vblank = ktime_set(0, 0);
 
 	tilcdc_crtc->enabled = false;
+out:
+	mutex_unlock(&tilcdc_crtc->enable_lock);
 }
 
 static bool tilcdc_crtc_is_on(struct drm_crtc *crtc)
@@ -819,6 +828,8 @@ struct drm_crtc *tilcdc_crtc_create(struct drm_device *dev)
 	drm_flip_work_init(&tilcdc_crtc->unref_work,
 			"unref", unref_worker);
 
+	mutex_init(&tilcdc_crtc->enable_lock);
+
 	spin_lock_init(&tilcdc_crtc->irq_lock);
 	INIT_WORK(&tilcdc_crtc->recover_work, tilcdc_crtc_recover_work);
 
-- 
1.9.1



More information about the dri-devel mailing list