diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c
index 4472862..0864c28 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -255,30 +255,6 @@ static const struct dss_mgr_ops mgr_ops = {
  * Setup, Flush and Page Flip
  */
 
-void omap_crtc_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file)
-{
-	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
-	struct drm_pending_vblank_event *event;
-	struct drm_device *dev = crtc->dev;
-	unsigned long flags;
-
-	/* Destroy the pending vertical blanking event associated with the
-	 * pending page flip, if any, and disable vertical blanking interrupts.
-	 */
-
-	spin_lock_irqsave(&dev->event_lock, flags);
-
-	event = omap_crtc->event;
-	omap_crtc->event = NULL;
-
-	if (event && event->base.file_priv == file) {
-		event->base.destroy(&event->base);
-		drm_crtc_vblank_put(crtc);
-	}
-
-	spin_unlock_irqrestore(&dev->event_lock, flags);
-}
-
 static void omap_crtc_complete_page_flip(struct drm_crtc *crtc)
 {
 	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
@@ -292,7 +268,17 @@ static void omap_crtc_complete_page_flip(struct drm_crtc *crtc)
 	omap_crtc->event = NULL;
 
 	if (event) {
-		drm_crtc_send_vblank_event(crtc, event);
+		list_del(&event->base.link);
+
+		/*
+		 * Queue the event for delivery if it's still linked to a file
+		 * handle, otherwise just destroy it.
+		 */
+		if (event->base.file_priv)
+			drm_crtc_send_vblank_event(crtc, event);
+		else
+			event->base.destroy(&event->base);
+
 		wake_up(&omap_crtc->flip_wait);
 		drm_crtc_vblank_put(crtc);
 	}
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c
index 14c8714..1ab8b13 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -105,6 +105,7 @@ static int omap_atomic_commit(struct drm_device *dev,
 {
 	struct omap_drm_private *priv = dev->dev_private;
 	struct omap_atomic_state_commit *commit;
+	unsigned long flags;
 	unsigned int i;
 	int ret;
 
@@ -141,6 +142,17 @@ static int omap_atomic_commit(struct drm_device *dev,
 		return ret;
 	}
 
+	/* Keep track of all CRTC events to unlink them in preclose(). */
+	spin_lock_irqsave(&dev->event_lock, flags);
+	for (i = 0; i < dev->mode_config.num_crtc; ++i) {
+		struct drm_crtc_state *cstate = state->crtc_states[i];
+
+		if (cstate && cstate->event)
+			list_add_tail(&cstate->event->base.link,
+				      &priv->commit.events);
+	}
+	spin_unlock_irqrestore(&dev->event_lock, flags);
+
 	/* Swap the state, this is the point of no return. */
 	drm_atomic_helper_swap_state(dev, state);
 
@@ -618,6 +630,7 @@ static int dev_load(struct drm_device *dev, unsigned long flags)
 
 	priv->wq = alloc_ordered_workqueue("omapdrm", 0);
 	init_waitqueue_head(&priv->commit.wait);
+	INIT_LIST_HEAD(&priv->commit.events);
 
 	spin_lock_init(&priv->list_lock);
 	INIT_LIST_HEAD(&priv->obj_list);
@@ -738,12 +751,23 @@ static void dev_lastclose(struct drm_device *dev)
 static void dev_preclose(struct drm_device *dev, struct drm_file *file)
 {
 	struct omap_drm_private *priv = dev->dev_private;
-	unsigned int i;
+	struct drm_pending_event *event;
+	unsigned long flags;
 
 	DBG("preclose: dev=%p", dev);
 
-	for (i = 0; i < priv->num_crtcs; ++i)
-		omap_crtc_cancel_page_flip(priv->crtcs[i], file);
+	/*
+	 * Unlink all pending CRTC events to make sure they won't be queued up
+	 * by a pending asynchronous commit.
+	 */
+	spin_lock_irqsave(&dev->event_lock, flags);
+	list_for_each_entry(event, &priv->commit.events, link) {
+		if (event->file_priv == file) {
+			file->event_space += event->event->length;
+			event->file_priv = NULL;
+		}
+	}
+	spin_unlock_irqrestore(&dev->event_lock, flags);
 }
 
 static void dev_postclose(struct drm_device *dev, struct drm_file *file)
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.h b/drivers/gpu/drm/omapdrm/omap_drv.h
index b105394..9cc2d34 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.h
+++ b/drivers/gpu/drm/omapdrm/omap_drv.h
@@ -109,6 +109,7 @@ struct omap_drm_private {
 
 	/* atomic commit */
 	struct {
+		struct list_head events;
 		wait_queue_head_t wait;
 		u32 pending;
 	} commit;
@@ -141,7 +142,6 @@ void omap_fbdev_free(struct drm_device *dev);
 
 const struct omap_video_timings *omap_crtc_timings(struct drm_crtc *crtc);
 enum omap_channel omap_crtc_channel(struct drm_crtc *crtc);
-void omap_crtc_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file);
 void omap_crtc_pre_init(void);
 void omap_crtc_pre_uninit(void);
 struct drm_crtc *omap_crtc_init(struct drm_device *dev,
