[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