@@ -238,3 +238,21 @@ void exynos_drm_crtc_te_handler(struct drm_crtc *crtc)
if (exynos_crtc->ops->te_handler)
exynos_crtc->ops->te_handler(exynos_crtc);
}
+
+void exynos_drm_crtc_cancel_page_flip(struct drm_crtc *crtc,
+ struct drm_file *file)
+{
+ struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
+ struct drm_pending_vblank_event *e;
+ unsigned long flags;
+
+ spin_lock_irqsave(&crtc->dev->event_lock, flags);
+ e = exynos_crtc->event;
+ if (e && e->base.file_priv == file) {
+ exynos_crtc->event = NULL;
+ e->base.destroy(&e->base);
+ file->event_space += sizeof(e->event);
+ atomic_dec(&exynos_crtc->pending_update);
+ }
+ spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
+}
@@ -40,4 +40,8 @@ int exynos_drm_crtc_get_pipe_from_type(struct drm_device *drm_dev,
*/
void exynos_drm_crtc_te_handler(struct drm_crtc *crtc);
+/* This function cancels a page flip request. */
+void exynos_drm_crtc_cancel_page_flip(struct drm_crtc *crtc,
+ struct drm_file *file);
+
#endif
@@ -369,7 +369,12 @@ err_file_priv_free:
static void exynos_drm_preclose(struct drm_device *dev,
struct drm_file *file)
{
+ struct drm_crtc *crtc;
+
exynos_drm_subdrv_close(dev, file);
+
+ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
+ exynos_drm_crtc_cancel_page_flip(crtc, file);
}
static void exynos_drm_postclose(struct drm_device *dev, struct drm_file *file)