return 0;
 }
 
+static void rockchip_drm_crtc_cancel_pending_vblank(struct drm_crtc *crtc,
+                                                   struct drm_file *file_priv)
+{
+       struct rockchip_drm_private *priv = crtc->dev->dev_private;
+       int pipe = drm_crtc_index(crtc);
+
+       if (pipe < ROCKCHIP_MAX_CRTC &&
+           priv->crtc_funcs[pipe] &&
+           priv->crtc_funcs[pipe]->cancel_pending_vblank)
+               priv->crtc_funcs[pipe]->cancel_pending_vblank(crtc, file_priv);
+}
+
+static void rockchip_drm_preclose(struct drm_device *dev,
+                                 struct drm_file *file_priv)
+{
+       struct drm_crtc *crtc;
+
+       list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
+               rockchip_drm_crtc_cancel_pending_vblank(crtc, file_priv);
+}
+
 void rockchip_drm_lastclose(struct drm_device *dev)
 {
        struct rockchip_drm_private *priv = dev->dev_private;
                                  DRIVER_PRIME | DRIVER_ATOMIC,
        .load                   = rockchip_drm_load,
        .unload                 = rockchip_drm_unload,
+       .preclose               = rockchip_drm_preclose,
        .lastclose              = rockchip_drm_lastclose,
        .get_vblank_counter     = drm_vblank_no_hw_counter,
        .enable_vblank          = rockchip_drm_crtc_enable_vblank,
 
        int (*enable_vblank)(struct drm_crtc *crtc);
        void (*disable_vblank)(struct drm_crtc *crtc);
        void (*wait_for_update)(struct drm_crtc *crtc);
+       void (*cancel_pending_vblank)(struct drm_crtc *crtc, struct drm_file *file_priv);
 };
 
 struct rockchip_atomic_commit {
 
        WARN_ON(!wait_for_completion_timeout(&vop->wait_update_complete, 100));
 }
 
+static void vop_crtc_cancel_pending_vblank(struct drm_crtc *crtc,
+                                          struct drm_file *file_priv)
+{
+       struct drm_device *drm = crtc->dev;
+       struct vop *vop = to_vop(crtc);
+       struct drm_pending_vblank_event *e;
+       unsigned long flags;
+
+       spin_lock_irqsave(&drm->event_lock, flags);
+       e = vop->event;
+       if (e && e->base.file_priv == file_priv) {
+               vop->event = NULL;
+
+               e->base.destroy(&e->base);
+               file_priv->event_space += sizeof(e->event);
+       }
+       spin_unlock_irqrestore(&drm->event_lock, flags);
+}
+
 static const struct rockchip_crtc_funcs private_crtc_funcs = {
        .enable_vblank = vop_crtc_enable_vblank,
        .disable_vblank = vop_crtc_disable_vblank,
        .wait_for_update = vop_crtc_wait_for_update,
+       .cancel_pending_vblank = vop_crtc_cancel_pending_vblank,
 };
 
 static bool vop_crtc_mode_fixup(struct drm_crtc *crtc,