Commit b3f5e732 authored by Chris Wilson's avatar Chris Wilson Committed by Dave Airlie

drm: Correct unbalanced drm_vblank_put() during mode setting.

The first time we install a mode, the vblank will be disabled for a pipe
and so drm_vblank_get() in drm_vblank_pre_modeset() will fail. As we
unconditionally call drm_vblank_put() afterwards, the vblank reference
counter becomes unbalanced.
Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Acked-by: default avatarJesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: default avatarDave Airlie <airlied@linux.ie>
parent 7bec756c
...@@ -435,6 +435,8 @@ EXPORT_SYMBOL(drm_vblank_get); ...@@ -435,6 +435,8 @@ EXPORT_SYMBOL(drm_vblank_get);
*/ */
void drm_vblank_put(struct drm_device *dev, int crtc) void drm_vblank_put(struct drm_device *dev, int crtc)
{ {
BUG_ON (atomic_read (&dev->vblank_refcount[crtc]) == 0);
/* Last user schedules interrupt disable */ /* Last user schedules interrupt disable */
if (atomic_dec_and_test(&dev->vblank_refcount[crtc])) if (atomic_dec_and_test(&dev->vblank_refcount[crtc]))
mod_timer(&dev->vblank_disable_timer, jiffies + 5*DRM_HZ); mod_timer(&dev->vblank_disable_timer, jiffies + 5*DRM_HZ);
...@@ -460,8 +462,9 @@ void drm_vblank_pre_modeset(struct drm_device *dev, int crtc) ...@@ -460,8 +462,9 @@ void drm_vblank_pre_modeset(struct drm_device *dev, int crtc)
* so that interrupts remain enabled in the interim. * so that interrupts remain enabled in the interim.
*/ */
if (!dev->vblank_inmodeset[crtc]) { if (!dev->vblank_inmodeset[crtc]) {
dev->vblank_inmodeset[crtc] = 1; dev->vblank_inmodeset[crtc] = 0x1;
drm_vblank_get(dev, crtc); if (drm_vblank_get(dev, crtc) == 0)
dev->vblank_inmodeset[crtc] |= 0x2;
} }
} }
EXPORT_SYMBOL(drm_vblank_pre_modeset); EXPORT_SYMBOL(drm_vblank_pre_modeset);
...@@ -473,9 +476,12 @@ void drm_vblank_post_modeset(struct drm_device *dev, int crtc) ...@@ -473,9 +476,12 @@ void drm_vblank_post_modeset(struct drm_device *dev, int crtc)
if (dev->vblank_inmodeset[crtc]) { if (dev->vblank_inmodeset[crtc]) {
spin_lock_irqsave(&dev->vbl_lock, irqflags); spin_lock_irqsave(&dev->vbl_lock, irqflags);
dev->vblank_disable_allowed = 1; dev->vblank_disable_allowed = 1;
dev->vblank_inmodeset[crtc] = 0;
spin_unlock_irqrestore(&dev->vbl_lock, irqflags); spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
drm_vblank_put(dev, crtc);
if (dev->vblank_inmodeset[crtc] & 0x2)
drm_vblank_put(dev, crtc);
dev->vblank_inmodeset[crtc] = 0;
} }
} }
EXPORT_SYMBOL(drm_vblank_post_modeset); EXPORT_SYMBOL(drm_vblank_post_modeset);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment