From: agoins <agoins@xxxxxxxxxx> 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@xxxxxxxxxx> --- 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 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel