diff options
Diffstat (limited to 'linux-core/drm_irq.c')
-rw-r--r-- | linux-core/drm_irq.c | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/linux-core/drm_irq.c b/linux-core/drm_irq.c index 7c056114..d0d6f987 100644 --- a/linux-core/drm_irq.c +++ b/linux-core/drm_irq.c @@ -82,11 +82,13 @@ static void vblank_disable_fn(unsigned long arg) for (i = 0; i < dev->num_crtcs; i++) { spin_lock_irqsave(&dev->vbl_lock, irqflags); - if (atomic_read(&dev->vblank_refcount[i]) == 0) { + if (atomic_read(&dev->vblank_refcount[i]) == 0 && + dev->vblank_enabled[i]) { DRM_DEBUG("disabling vblank on crtc %d\n", i); dev->last_vblank[i] = dev->driver->get_vblank_counter(dev, i); dev->driver->disable_vblank(dev, i); + dev->vblank_enabled[i] = 0; } spin_unlock_irqrestore(&dev->vbl_lock, irqflags); } @@ -110,6 +112,8 @@ static void drm_vblank_cleanup(struct drm_device *dev) dev->num_crtcs, DRM_MEM_DRIVER); drm_free(dev->vblank_refcount, sizeof(*dev->vblank_refcount) * dev->num_crtcs, DRM_MEM_DRIVER); + drm_free(dev->vblank_enabled, sizeof(*dev->vblank_enabled) * + dev->num_crtcs, DRM_MEM_DRIVER); drm_free(dev->last_vblank, sizeof(*dev->last_vblank) * dev->num_crtcs, DRM_MEM_DRIVER); drm_free(dev->vblank_inmodeset, sizeof(*dev->vblank_inmodeset) * @@ -148,6 +152,11 @@ int drm_vblank_init(struct drm_device *dev, int num_crtcs) if (!dev->vblank_refcount) goto err; + dev->vblank_enabled = drm_calloc(num_crtcs, sizeof(int), + DRM_MEM_DRIVER); + if (!dev->vblank_enabled) + goto err; + dev->last_vblank = drm_calloc(num_crtcs, sizeof(u32), DRM_MEM_DRIVER); if (!dev->last_vblank) goto err; @@ -387,12 +396,15 @@ int drm_vblank_get(struct drm_device *dev, int crtc) spin_lock_irqsave(&dev->vbl_lock, irqflags); /* Going from 0->1 means we have to enable interrupts again */ - if (atomic_add_return(1, &dev->vblank_refcount[crtc]) == 1) { + if (atomic_add_return(1, &dev->vblank_refcount[crtc]) == 1 && + !dev->vblank_enabled[crtc]) { ret = dev->driver->enable_vblank(dev, crtc); if (ret) atomic_dec(&dev->vblank_refcount[crtc]); - else + else { + dev->vblank_enabled[crtc] = 1; drm_update_vblank_count(dev, crtc); + } } spin_unlock_irqrestore(&dev->vbl_lock, irqflags); |