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: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Dave Airlie <airlied@linux.ie>
This commit is contained in:
parent
7bec756c74
commit
b3f5e7329d
1 changed files with 10 additions and 4 deletions
|
@ -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)
|
||||||
* 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)
|
||||||
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);
|
||||||
|
|
Loading…
Reference in a new issue