[PATCH drm 1/6] drm: factor out drm_mode_page_flip_ioctl()

Alex Goins agoins at nvidia.com
Thu Oct 22 13:00:54 PDT 2015


From: agoins <agoins at nvidia.com>

Factors contents of drm_mode_page_flip_ioctl() into drm_mode_page_flip(),
allowing it to be callable from the kernel within DRM. Replace contents of
drm_mode_page_flip_ioctl() with a call to drm_mode_page_flip().

Signed-off-by: Alex Goins <agoins at nvidia.com>
---
 drivers/gpu/drm/drm_crtc.c | 90 +++++++++++++++++++++++++++++++---------------
 include/drm/drm_crtc.h     |  4 +++
 2 files changed, 66 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index e54660a..503b651 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -5126,41 +5126,40 @@ out:
 }
 
 /**
- * drm_mode_page_flip_ioctl - schedule an asynchronous fb update
+ * drm_mode_page_flip - schedule an asynchronous fb update
  * @dev: DRM device
- * @data: ioctl data
+ * @crtc_id: CRTC to update
+ * @fb_id: FB to update to
+ * @flags: Flags modifying page flip behavior.
+ * @user_data: Returned as user_data field in in the vblank event struct
  * @file_priv: DRM file info
  *
  * This schedules an asynchronous update on a given CRTC, called page flip.
  * Optionally a drm event is generated to signal the completion of the event.
  * Generic drivers cannot assume that a pageflip with changed framebuffer
  * properties (including driver specific metadata like tiling layout) will work,
- * but some drivers support e.g. pixel format changes through the pageflip
- * ioctl.
- *
- * Called by the user via ioctl.
+ * but some drivers support e.g. pixel format changes through the pageflip.
  *
  * Returns:
  * Zero on success, negative errno on failure.
  */
-int drm_mode_page_flip_ioctl(struct drm_device *dev,
-			     void *data, struct drm_file *file_priv)
+int drm_mode_page_flip(struct drm_device *dev,
+		       uint32_t crtc_id, uint32_t fb_id,
+		       uint32_t flags, uint64_t user_data,
+		       struct drm_file *file_priv)
 {
-	struct drm_mode_crtc_page_flip *page_flip = data;
 	struct drm_crtc *crtc;
 	struct drm_framebuffer *fb = NULL;
 	struct drm_pending_vblank_event *e = NULL;
-	unsigned long flags;
+	unsigned long lock_flags;
 	int ret = -EINVAL;
 
-	if (page_flip->flags & ~DRM_MODE_PAGE_FLIP_FLAGS ||
-	    page_flip->reserved != 0)
-		return -EINVAL;
-
-	if ((page_flip->flags & DRM_MODE_PAGE_FLIP_ASYNC) && !dev->mode_config.async_page_flip)
+	if ((flags & DRM_MODE_PAGE_FLIP_ASYNC) &&
+	    !dev->mode_config.async_page_flip) {
 		return -EINVAL;
+	}
 
-	crtc = drm_crtc_find(dev, page_flip->crtc_id);
+	crtc = drm_crtc_find(dev, crtc_id);
 	if (!crtc)
 		return -ENOENT;
 
@@ -5177,7 +5176,7 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
 	if (crtc->funcs->page_flip == NULL)
 		goto out;
 
-	fb = drm_framebuffer_lookup(dev, page_flip->fb_id);
+	fb = drm_framebuffer_lookup(dev, fb_id);
 	if (!fb) {
 		ret = -ENOENT;
 		goto out;
@@ -5200,27 +5199,27 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
 		goto out;
 	}
 
-	if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) {
+	if (flags & DRM_MODE_PAGE_FLIP_EVENT) {
 		ret = -ENOMEM;
-		spin_lock_irqsave(&dev->event_lock, flags);
+		spin_lock_irqsave(&dev->event_lock, lock_flags);
 		if (file_priv->event_space < sizeof(e->event)) {
-			spin_unlock_irqrestore(&dev->event_lock, flags);
+			spin_unlock_irqrestore(&dev->event_lock, lock_flags);
 			goto out;
 		}
 		file_priv->event_space -= sizeof(e->event);
-		spin_unlock_irqrestore(&dev->event_lock, flags);
+		spin_unlock_irqrestore(&dev->event_lock, lock_flags);
 
 		e = kzalloc(sizeof(*e), GFP_KERNEL);
 		if (e == NULL) {
-			spin_lock_irqsave(&dev->event_lock, flags);
+			spin_lock_irqsave(&dev->event_lock, lock_flags);
 			file_priv->event_space += sizeof(e->event);
-			spin_unlock_irqrestore(&dev->event_lock, flags);
+			spin_unlock_irqrestore(&dev->event_lock, lock_flags);
 			goto out;
 		}
 
 		e->event.base.type = DRM_EVENT_FLIP_COMPLETE;
 		e->event.base.length = sizeof(e->event);
-		e->event.user_data = page_flip->user_data;
+		e->event.user_data = user_data;
 		e->base.event = &e->event.base;
 		e->base.file_priv = file_priv;
 		e->base.destroy =
@@ -5228,12 +5227,12 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
 	}
 
 	crtc->primary->old_fb = crtc->primary->fb;
-	ret = crtc->funcs->page_flip(crtc, fb, e, page_flip->flags);
+	ret = crtc->funcs->page_flip(crtc, fb, e, flags);
 	if (ret) {
-		if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) {
-			spin_lock_irqsave(&dev->event_lock, flags);
+		if (flags & DRM_MODE_PAGE_FLIP_EVENT) {
+			spin_lock_irqsave(&dev->event_lock, lock_flags);
 			file_priv->event_space += sizeof(e->event);
-			spin_unlock_irqrestore(&dev->event_lock, flags);
+			spin_unlock_irqrestore(&dev->event_lock, lock_flags);
 			kfree(e);
 		}
 		/* Keep the old fb, don't unref it. */
@@ -5256,6 +5255,41 @@ out:
 }
 
 /**
+ * drm_mode_page_flip_ioctl - schedule an asynchronous fb update
+ * @dev: DRM device
+ * @data: ioctl data
+ * @file_priv: DRM file info
+ *
+ * This schedules an asynchronous update on a given CRTC, called page flip.
+ * Optionally a drm event is generated to signal the completion of the event.
+ * Generic drivers cannot assume that a pageflip with changed framebuffer
+ * properties (including driver specific metadata like tiling layout) will work,
+ * but some drivers support e.g. pixel format changes through the pageflip
+ * ioctl.
+ *
+ * Called by the user via ioctl.
+ *
+ * Returns:
+ * Zero on success, negative errno on failure.
+ */
+int drm_mode_page_flip_ioctl(struct drm_device *dev,
+			     void *data, struct drm_file *file_priv)
+{
+	struct drm_mode_crtc_page_flip *page_flip = data;
+
+	if (page_flip->reserved != 0)
+		return -EINVAL;
+
+	if (page_flip->flags & ~DRM_MODE_PAGE_FLIP_FLAGS)
+		return -EINVAL;
+
+	return drm_mode_page_flip(dev,
+				  page_flip->crtc_id, page_flip->fb_id,
+				  page_flip->flags, page_flip->user_data,
+				  file_priv);
+}
+
+/**
  * drm_mode_config_reset - call ->reset callbacks
  * @dev: drm device
  *
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 3f0c690..8a6ff73 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -1448,6 +1448,10 @@ extern enum hdmi_picture_aspect drm_get_cea_aspect_ratio(const u8 video_code);
 extern bool drm_detect_hdmi_monitor(struct edid *edid);
 extern bool drm_detect_monitor_audio(struct edid *edid);
 extern bool drm_rgb_quant_range_selectable(struct edid *edid);
+extern int drm_mode_page_flip(struct drm_device *dev,
+			      uint32_t crtc_id, uint32_t fb_id,
+			      uint32_t flags, uint64_t user_data,
+			      struct drm_file *file_priv);
 extern int drm_mode_page_flip_ioctl(struct drm_device *dev,
 				    void *data, struct drm_file *file_priv);
 extern int drm_add_modes_noedid(struct drm_connector *connector,
-- 
1.9.1



More information about the dri-devel mailing list