diff mbox

[70/72] imx-drm: Cancel pending page flip events at preclose

Message ID 1414796095-10107-71-git-send-email-steve_longerbeam@mentor.com (mailing list archive)
State New, archived
Headers show

Commit Message

Steve Longerbeam Oct. 31, 2014, 10:54 p.m. UTC
At preclose, destroy page flip events that are pending on every
plane.

Signed-off-by: Steve Longerbeam <steve_longerbeam@mentor.com>
---
 drivers/staging/imx-drm/imx-drm-core.c |   15 +++++++++++++--
 drivers/staging/imx-drm/imx-drm.h      |    2 ++
 drivers/staging/imx-drm/ipuv3-crtc.c   |   13 +++++++++++++
 drivers/staging/imx-drm/ipuv3-plane.c  |   22 ++++++++++++++++++++++
 drivers/staging/imx-drm/ipuv3-plane.h  |    2 ++
 5 files changed, 52 insertions(+), 2 deletions(-)
diff mbox

Patch

diff --git a/drivers/staging/imx-drm/imx-drm-core.c b/drivers/staging/imx-drm/imx-drm-core.c
index b31d291..b2cc77b 100644
--- a/drivers/staging/imx-drm/imx-drm-core.c
+++ b/drivers/staging/imx-drm/imx-drm-core.c
@@ -213,13 +213,24 @@  static void imx_drm_disable_vblank(struct drm_device *drm, int pipe)
 static void imx_drm_driver_preclose(struct drm_device *drm,
 		struct drm_file *file)
 {
+	struct imx_drm_device *imxdrm = drm->dev_private;
+	struct imx_drm_crtc_helper_funcs *helpers;
+	struct imx_drm_crtc *imx_drm_crtc;
 	int pipe;
 
 	if (!file->is_master)
 		return;
 
-	for (pipe = 0; pipe < MAX_PIPES; pipe++)
-		imx_drm_disable_vblank(drm, pipe);
+	for (pipe = 0; pipe < MAX_PIPES; pipe++) {
+		imx_drm_crtc = imxdrm->crtc[pipe_to_crtc_id(pipe)];
+		if (!imx_drm_crtc)
+			continue;
+		helpers = &imx_drm_crtc->imx_drm_helper_funcs;
+		if (!helpers->cancel_page_flip)
+			continue;
+
+		helpers->cancel_page_flip(imx_drm_crtc->crtc, file, pipe);
+	}
 }
 
 static const struct file_operations imx_drm_driver_fops = {
diff --git a/drivers/staging/imx-drm/imx-drm.h b/drivers/staging/imx-drm/imx-drm.h
index 24b889a..8ffcc0a 100644
--- a/drivers/staging/imx-drm/imx-drm.h
+++ b/drivers/staging/imx-drm/imx-drm.h
@@ -21,6 +21,8 @@  int imx_drm_overlay_plane_pipe(struct imx_drm_crtc *crtc);
 struct imx_drm_crtc_helper_funcs {
 	int (*enable_vblank)(struct drm_crtc *crtc, int pipe);
 	void (*disable_vblank)(struct drm_crtc *crtc, int pipe);
+	void (*cancel_page_flip)(struct drm_crtc *crtc, struct drm_file *file,
+				 int pipe);
 	int (*set_interface_pix_fmt)(struct drm_crtc *crtc, u32 encoder_type,
 				     u32 pix_fmt, struct ipu_dc_if_map *pix_map,
 				     int hsync_pin, int vsync_pin);
diff --git a/drivers/staging/imx-drm/ipuv3-crtc.c b/drivers/staging/imx-drm/ipuv3-crtc.c
index 179b764..7d5b691 100644
--- a/drivers/staging/imx-drm/ipuv3-crtc.c
+++ b/drivers/staging/imx-drm/ipuv3-crtc.c
@@ -398,6 +398,18 @@  static void ipu_disable_vblank(struct drm_crtc *crtc, int pipe)
 	ipu_plane_disable_vblank(ipu_plane);
 }
 
+static void ipu_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file,
+				 int pipe)
+{
+	struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
+	struct ipu_plane *ipu_plane = pipe_to_plane(ipu_crtc, pipe);
+
+	if (!ipu_plane)
+		return;
+
+	ipu_plane_cancel_page_flip(ipu_plane, file);
+}
+
 static int ipu_set_interface_pix_fmt(struct drm_crtc *crtc, u32 encoder_type,
 				     u32 pixfmt, struct ipu_dc_if_map *pixmap,
 				     int hsync_pin, int vsync_pin)
@@ -435,6 +447,7 @@  static int ipu_gamma_set(struct drm_crtc *crtc, bool enable, u32 *m, u32 *b)
 static const struct imx_drm_crtc_helper_funcs ipu_crtc_helper_funcs = {
 	.enable_vblank = ipu_enable_vblank,
 	.disable_vblank = ipu_disable_vblank,
+	.cancel_page_flip = ipu_cancel_page_flip,
 	.set_interface_pix_fmt = ipu_set_interface_pix_fmt,
 	.gamma_set = ipu_gamma_set,
 	.crtc_funcs = &ipu_crtc_funcs,
diff --git a/drivers/staging/imx-drm/ipuv3-plane.c b/drivers/staging/imx-drm/ipuv3-plane.c
index aa10ae7..c012c4e 100644
--- a/drivers/staging/imx-drm/ipuv3-plane.c
+++ b/drivers/staging/imx-drm/ipuv3-plane.c
@@ -150,6 +150,28 @@  void ipu_plane_disable_vblank(struct ipu_plane *ipu_plane)
 	ipu_plane->newfb = NULL;
 }
 
+void ipu_plane_cancel_page_flip(struct ipu_plane *ipu_plane,
+				struct drm_file *file)
+{
+	struct drm_device *drm = ipu_plane->base.dev;
+	struct drm_pending_vblank_event *event;
+	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(&drm->event_lock, flags);
+	event = ipu_plane->page_flip_event;
+	if (event && event->base.file_priv == file) {
+		ipu_plane->page_flip_event = NULL;
+		ipu_plane->newfb = NULL;
+		event->base.destroy(&event->base);
+		drm_vblank_put(drm, ipu_plane->pipe);
+	}
+	spin_unlock_irqrestore(&drm->event_lock, flags);
+}
+
 int ipu_plane_mode_set(struct ipu_plane *ipu_plane, struct drm_crtc *crtc,
 		       struct drm_display_mode *mode,
 		       struct drm_framebuffer *fb, int crtc_x, int crtc_y,
diff --git a/drivers/staging/imx-drm/ipuv3-plane.h b/drivers/staging/imx-drm/ipuv3-plane.h
index 912902a..c584a6a 100644
--- a/drivers/staging/imx-drm/ipuv3-plane.h
+++ b/drivers/staging/imx-drm/ipuv3-plane.h
@@ -63,6 +63,8 @@  int ipu_plane_page_flip(struct drm_plane *plane,
 
 int ipu_plane_enable_vblank(struct ipu_plane *ipu_plane);
 void ipu_plane_disable_vblank(struct ipu_plane *ipu_plane);
+void ipu_plane_cancel_page_flip(struct ipu_plane *ipu_plane,
+				struct drm_file *file);
 
 void ipu_plane_enable(struct ipu_plane *plane);
 void ipu_plane_disable(struct ipu_plane *plane);