|
@@ -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);
|