diff options
Diffstat (limited to 'drivers/gpu/drm/drm_irq.c')
| -rw-r--r-- | drivers/gpu/drm/drm_irq.c | 23 | 
1 files changed, 23 insertions, 0 deletions
| diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 741457bd1c46..a1f12cb043de 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -932,11 +932,34 @@ EXPORT_SYMBOL(drm_vblank_put);  void drm_vblank_off(struct drm_device *dev, int crtc)  { +	struct drm_pending_vblank_event *e, *t; +	struct timeval now;  	unsigned long irqflags; +	unsigned int seq;  	spin_lock_irqsave(&dev->vbl_lock, irqflags);  	vblank_disable_and_save(dev, crtc);  	DRM_WAKEUP(&dev->vbl_queue[crtc]); + +	/* Send any queued vblank events, lest the natives grow disquiet */ +	seq = drm_vblank_count_and_time(dev, crtc, &now); +	list_for_each_entry_safe(e, t, &dev->vblank_event_list, base.link) { +		if (e->pipe != crtc) +			continue; +		DRM_DEBUG("Sending premature vblank event on disable: \ +			  wanted %d, current %d\n", +			  e->event.sequence, seq); + +		e->event.sequence = seq; +		e->event.tv_sec = now.tv_sec; +		e->event.tv_usec = now.tv_usec; +		drm_vblank_put(dev, e->pipe); +		list_move_tail(&e->base.link, &e->base.file_priv->event_list); +		wake_up_interruptible(&e->base.file_priv->event_wait); +		trace_drm_vblank_event_delivered(e->base.pid, e->pipe, +						 e->event.sequence); +	} +  	spin_unlock_irqrestore(&dev->vbl_lock, irqflags);  }  EXPORT_SYMBOL(drm_vblank_off); |