]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
drm: omapdrm: Handle events when enabling/disabling CRTCs
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Mon, 8 May 2017 22:27:09 +0000 (01:27 +0300)
committerTomi Valkeinen <tomi.valkeinen@ti.com>
Fri, 2 Jun 2017 07:53:41 +0000 (10:53 +0300)
The driver currently handles vblank events only when updating planes on
an already enabled CRTC. The atomic update API however allows requesting
an event when enabling or disabling a CRTC. This currently leads to
event objects being leaked in the kernel and to events not being sent
out. Fix it.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
drivers/gpu/drm/omapdrm/omap_crtc.c

index dccd037267966894ac8831d0891e200cf36a98d7..dd0ef40ca46929ee192b6e2bcf7fbc9a44721d84 100644 (file)
@@ -343,6 +343,19 @@ static void omap_crtc_destroy(struct drm_crtc *crtc)
        kfree(omap_crtc);
 }
 
+static void omap_crtc_arm_event(struct drm_crtc *crtc)
+{
+       struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
+
+       WARN_ON(omap_crtc->pending);
+       omap_crtc->pending = true;
+
+       if (crtc->state->event) {
+               omap_crtc->event = crtc->state->event;
+               crtc->state->event = NULL;
+       }
+}
+
 static void omap_crtc_enable(struct drm_crtc *crtc)
 {
        struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
@@ -355,8 +368,7 @@ static void omap_crtc_enable(struct drm_crtc *crtc)
        ret = drm_crtc_vblank_get(crtc);
        WARN_ON(ret != 0);
 
-       WARN_ON(omap_crtc->pending);
-       omap_crtc->pending = true;
+       omap_crtc_arm_event(crtc);
        spin_unlock_irq(&crtc->dev->event_lock);
 }
 
@@ -366,6 +378,13 @@ static void omap_crtc_disable(struct drm_crtc *crtc)
 
        DBG("%s", omap_crtc->name);
 
+       spin_lock_irq(&crtc->dev->event_lock);
+       if (crtc->state->event) {
+               drm_crtc_send_vblank_event(crtc, crtc->state->event);
+               crtc->state->event = NULL;
+       }
+       spin_unlock_irq(&crtc->dev->event_lock);
+
        drm_crtc_vblank_off(crtc);
 }
 
@@ -473,12 +492,7 @@ static void omap_crtc_atomic_flush(struct drm_crtc *crtc,
 
        spin_lock_irq(&crtc->dev->event_lock);
        priv->dispc_ops->mgr_go(omap_crtc->channel);
-
-       WARN_ON(omap_crtc->pending);
-       omap_crtc->pending = true;
-
-       if (crtc->state->event)
-               omap_crtc->event = crtc->state->event;
+       omap_crtc_arm_event(crtc);
        spin_unlock_irq(&crtc->dev->event_lock);
 }