aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
authorChristopher James Halse Rogers <christopher.halse.rogers@canonical.com>2011-04-27 02:10:57 -0400
committerDave Airlie <airlied@redhat.com>2011-05-03 20:11:55 -0400
commit498548ec69c6897fe4376b2ca90758762fa0b817 (patch)
tree9e7fa6f5d7e58ab2acb688c7a9e4653856cf4e49 /drivers/gpu/drm
parenteaa4f5e1d0b816291a59a47917e569c0384f2b6f (diff)
drm: Send pending vblank events before disabling vblank.
This is the least-bad behaviour. It means that we signal the vblank event before it actually happens, but since we're disabling vblanks there's no guarantee that it will *ever* happen otherwise. This prevents GL applications which use WaitMSC from hanging indefinitely. Signed-off-by: Christopher James Halse Rogers <christopher.halse.rogers@canonical.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r--drivers/gpu/drm/drm_irq.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index 741457bd1c4..a1f12cb043d 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -932,11 +932,34 @@ EXPORT_SYMBOL(drm_vblank_put);
932 932
933void drm_vblank_off(struct drm_device *dev, int crtc) 933void drm_vblank_off(struct drm_device *dev, int crtc)
934{ 934{
935 struct drm_pending_vblank_event *e, *t;
936 struct timeval now;
935 unsigned long irqflags; 937 unsigned long irqflags;
938 unsigned int seq;
936 939
937 spin_lock_irqsave(&dev->vbl_lock, irqflags); 940 spin_lock_irqsave(&dev->vbl_lock, irqflags);
938 vblank_disable_and_save(dev, crtc); 941 vblank_disable_and_save(dev, crtc);
939 DRM_WAKEUP(&dev->vbl_queue[crtc]); 942 DRM_WAKEUP(&dev->vbl_queue[crtc]);
943
944 /* Send any queued vblank events, lest the natives grow disquiet */
945 seq = drm_vblank_count_and_time(dev, crtc, &now);
946 list_for_each_entry_safe(e, t, &dev->vblank_event_list, base.link) {
947 if (e->pipe != crtc)
948 continue;
949 DRM_DEBUG("Sending premature vblank event on disable: \
950 wanted %d, current %d\n",
951 e->event.sequence, seq);
952
953 e->event.sequence = seq;
954 e->event.tv_sec = now.tv_sec;
955 e->event.tv_usec = now.tv_usec;
956 drm_vblank_put(dev, e->pipe);
957 list_move_tail(&e->base.link, &e->base.file_priv->event_list);
958 wake_up_interruptible(&e->base.file_priv->event_wait);
959 trace_drm_vblank_event_delivered(e->base.pid, e->pipe,
960 e->event.sequence);
961 }
962
940 spin_unlock_irqrestore(&dev->vbl_lock, irqflags); 963 spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
941} 964}
942EXPORT_SYMBOL(drm_vblank_off); 965EXPORT_SYMBOL(drm_vblank_off);