aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/omapdrm/omap_crtc.c
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2017-05-08 18:27:09 -0400
committerTomi Valkeinen <tomi.valkeinen@ti.com>2017-06-02 03:53:41 -0400
commitce9a8f1ad7564fa24bc12066b41f2a09eb1a8394 (patch)
tree909ee2e197f015502f0552523c9c002f020c5602 /drivers/gpu/drm/omapdrm/omap_crtc.c
parent2a1720376adda5ecf8e636fbfb05339c7dad1c55 (diff)
drm: omapdrm: Handle events when enabling/disabling CRTCs
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>
Diffstat (limited to 'drivers/gpu/drm/omapdrm/omap_crtc.c')
-rw-r--r--drivers/gpu/drm/omapdrm/omap_crtc.c30
1 files changed, 22 insertions, 8 deletions
diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c
index dccd03726796..dd0ef40ca469 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -343,6 +343,19 @@ static void omap_crtc_destroy(struct drm_crtc *crtc)
343 kfree(omap_crtc); 343 kfree(omap_crtc);
344} 344}
345 345
346static void omap_crtc_arm_event(struct drm_crtc *crtc)
347{
348 struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
349
350 WARN_ON(omap_crtc->pending);
351 omap_crtc->pending = true;
352
353 if (crtc->state->event) {
354 omap_crtc->event = crtc->state->event;
355 crtc->state->event = NULL;
356 }
357}
358
346static void omap_crtc_enable(struct drm_crtc *crtc) 359static void omap_crtc_enable(struct drm_crtc *crtc)
347{ 360{
348 struct omap_crtc *omap_crtc = to_omap_crtc(crtc); 361 struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
@@ -355,8 +368,7 @@ static void omap_crtc_enable(struct drm_crtc *crtc)
355 ret = drm_crtc_vblank_get(crtc); 368 ret = drm_crtc_vblank_get(crtc);
356 WARN_ON(ret != 0); 369 WARN_ON(ret != 0);
357 370
358 WARN_ON(omap_crtc->pending); 371 omap_crtc_arm_event(crtc);
359 omap_crtc->pending = true;
360 spin_unlock_irq(&crtc->dev->event_lock); 372 spin_unlock_irq(&crtc->dev->event_lock);
361} 373}
362 374
@@ -366,6 +378,13 @@ static void omap_crtc_disable(struct drm_crtc *crtc)
366 378
367 DBG("%s", omap_crtc->name); 379 DBG("%s", omap_crtc->name);
368 380
381 spin_lock_irq(&crtc->dev->event_lock);
382 if (crtc->state->event) {
383 drm_crtc_send_vblank_event(crtc, crtc->state->event);
384 crtc->state->event = NULL;
385 }
386 spin_unlock_irq(&crtc->dev->event_lock);
387
369 drm_crtc_vblank_off(crtc); 388 drm_crtc_vblank_off(crtc);
370} 389}
371 390
@@ -473,12 +492,7 @@ static void omap_crtc_atomic_flush(struct drm_crtc *crtc,
473 492
474 spin_lock_irq(&crtc->dev->event_lock); 493 spin_lock_irq(&crtc->dev->event_lock);
475 priv->dispc_ops->mgr_go(omap_crtc->channel); 494 priv->dispc_ops->mgr_go(omap_crtc->channel);
476 495 omap_crtc_arm_event(crtc);
477 WARN_ON(omap_crtc->pending);
478 omap_crtc->pending = true;
479
480 if (crtc->state->event)
481 omap_crtc->event = crtc->state->event;
482 spin_unlock_irq(&crtc->dev->event_lock); 496 spin_unlock_irq(&crtc->dev->event_lock);
483} 497}
484 498