{
        struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
        unsigned long irqflags;
+       bool disable_irq;
 
        if (WARN_ON_ONCE(!dev->num_crtcs))
                return false;
        spin_unlock(&dev->vblank_time_lock);
 
        wake_up(&vblank->queue);
-       drm_handle_vblank_events(dev, pipe);
 
        /* With instant-off, we defer disabling the interrupt until after
-        * we finish processing the following vblank. The disable has to
-        * be last (after drm_handle_vblank_events) so that the timestamp
-        * is always accurate.
+        * we finish processing the following vblank after all events have
+        * been signaled. The disable has to be last (after
+        * drm_handle_vblank_events) so that the timestamp is always accurate.
         */
-       if (dev->vblank_disable_immediate &&
-           drm_vblank_offdelay > 0 &&
-           !atomic_read(&vblank->refcount))
-               vblank_disable_fn((unsigned long)vblank);
+       disable_irq = (dev->vblank_disable_immediate &&
+                      drm_vblank_offdelay > 0 &&
+                      !atomic_read(&vblank->refcount));
+
+       drm_handle_vblank_events(dev, pipe);
 
        spin_unlock_irqrestore(&dev->event_lock, irqflags);
 
+       if (disable_irq)
+               vblank_disable_fn((unsigned long)vblank);
+
        return true;
 }
 EXPORT_SYMBOL(drm_handle_vblank);