mirror of https://gitee.com/openkylin/linux.git
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>
This commit is contained in:
parent
2a1720376a
commit
ce9a8f1ad7
|
@ -343,6 +343,19 @@ static void omap_crtc_destroy(struct drm_crtc *crtc)
|
||||||
kfree(omap_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)
|
static void omap_crtc_enable(struct drm_crtc *crtc)
|
||||||
{
|
{
|
||||||
struct omap_crtc *omap_crtc = to_omap_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);
|
ret = drm_crtc_vblank_get(crtc);
|
||||||
WARN_ON(ret != 0);
|
WARN_ON(ret != 0);
|
||||||
|
|
||||||
WARN_ON(omap_crtc->pending);
|
omap_crtc_arm_event(crtc);
|
||||||
omap_crtc->pending = true;
|
|
||||||
spin_unlock_irq(&crtc->dev->event_lock);
|
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);
|
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);
|
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);
|
spin_lock_irq(&crtc->dev->event_lock);
|
||||||
priv->dispc_ops->mgr_go(omap_crtc->channel);
|
priv->dispc_ops->mgr_go(omap_crtc->channel);
|
||||||
|
omap_crtc_arm_event(crtc);
|
||||||
WARN_ON(omap_crtc->pending);
|
|
||||||
omap_crtc->pending = true;
|
|
||||||
|
|
||||||
if (crtc->state->event)
|
|
||||||
omap_crtc->event = crtc->state->event;
|
|
||||||
spin_unlock_irq(&crtc->dev->event_lock);
|
spin_unlock_irq(&crtc->dev->event_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue