parent
f529a510d2
commit
4be367b84b
|
@ -848,6 +848,8 @@ struct drm_device {
|
|||
atomic_t *vblank_refcount; /* number of users of vblank interrupts per crtc */
|
||||
u32 *last_vblank; /* protected by dev->vbl_lock, used */
|
||||
/* for wraparound handling */
|
||||
int *vblank_enabled; /* so we don't call enable more than
|
||||
once per disable */
|
||||
int *vblank_inmodeset; /* Display driver is setting mode */
|
||||
struct timer_list vblank_disable_timer;
|
||||
|
||||
|
|
|
@ -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,13 +396,16 @@ 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);
|
||||
|
||||
return ret;
|
||||
|
|
Loading…
Reference in New Issue