提交 c394c2b0 编写于 作者: M Matt Roper 提交者: Daniel Vetter

drm: Refactor framebuffer creation to allow internal use (v2)

Refactor DRM framebuffer creation into a new function that returns a
struct drm_framebuffer directly.  The upcoming universal cursor support
will want to create framebuffers internally to wrap cursor buffers, so
we want to be able to share that framebuffer creation with the
drm_mode_addfb2 ioctl handler.

v2: Take struct drm_mode_fb_cmd2 parameter directly rather than void*
Reviewed-by: NDaniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: NMatt Roper <matthew.d.roper@intel.com>
Reviewed-by: Pallavi G<pallavi.g@intel.com>
Acked-by: NDave Airlie <airlied@linux.ie>
Signed-off-by: NDaniel Vetter <daniel.vetter@ffwll.ch>
上级 7405f42c
...@@ -41,6 +41,10 @@ ...@@ -41,6 +41,10 @@
#include "drm_crtc_internal.h" #include "drm_crtc_internal.h"
static struct drm_framebuffer *add_framebuffer_internal(struct drm_device *dev,
struct drm_mode_fb_cmd2 *r,
struct drm_file *file_priv);
/** /**
* drm_modeset_lock_all - take all modeset locks * drm_modeset_lock_all - take all modeset locks
* @dev: drm device * @dev: drm device
...@@ -2827,56 +2831,38 @@ static int framebuffer_check(const struct drm_mode_fb_cmd2 *r) ...@@ -2827,56 +2831,38 @@ static int framebuffer_check(const struct drm_mode_fb_cmd2 *r)
return 0; return 0;
} }
/** static struct drm_framebuffer *add_framebuffer_internal(struct drm_device *dev,
* drm_mode_addfb2 - add an FB to the graphics configuration struct drm_mode_fb_cmd2 *r,
* @dev: drm device for the ioctl struct drm_file *file_priv)
* @data: data pointer for the ioctl
* @file_priv: drm file for the ioctl call
*
* Add a new FB to the specified CRTC, given a user request with format. This is
* the 2nd version of the addfb ioctl, which supports multi-planar framebuffers
* and uses fourcc codes as pixel format specifiers.
*
* Called by the user via ioctl.
*
* Returns:
* Zero on success, errno on failure.
*/
int drm_mode_addfb2(struct drm_device *dev,
void *data, struct drm_file *file_priv)
{ {
struct drm_mode_fb_cmd2 *r = data;
struct drm_mode_config *config = &dev->mode_config; struct drm_mode_config *config = &dev->mode_config;
struct drm_framebuffer *fb; struct drm_framebuffer *fb;
int ret; int ret;
if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;
if (r->flags & ~DRM_MODE_FB_INTERLACED) { if (r->flags & ~DRM_MODE_FB_INTERLACED) {
DRM_DEBUG_KMS("bad framebuffer flags 0x%08x\n", r->flags); DRM_DEBUG_KMS("bad framebuffer flags 0x%08x\n", r->flags);
return -EINVAL; return ERR_PTR(-EINVAL);
} }
if ((config->min_width > r->width) || (r->width > config->max_width)) { if ((config->min_width > r->width) || (r->width > config->max_width)) {
DRM_DEBUG_KMS("bad framebuffer width %d, should be >= %d && <= %d\n", DRM_DEBUG_KMS("bad framebuffer width %d, should be >= %d && <= %d\n",
r->width, config->min_width, config->max_width); r->width, config->min_width, config->max_width);
return -EINVAL; return ERR_PTR(-EINVAL);
} }
if ((config->min_height > r->height) || (r->height > config->max_height)) { if ((config->min_height > r->height) || (r->height > config->max_height)) {
DRM_DEBUG_KMS("bad framebuffer height %d, should be >= %d && <= %d\n", DRM_DEBUG_KMS("bad framebuffer height %d, should be >= %d && <= %d\n",
r->height, config->min_height, config->max_height); r->height, config->min_height, config->max_height);
return -EINVAL; return ERR_PTR(-EINVAL);
} }
ret = framebuffer_check(r); ret = framebuffer_check(r);
if (ret) if (ret)
return ret; return ERR_PTR(ret);
fb = dev->mode_config.funcs->fb_create(dev, file_priv, r); fb = dev->mode_config.funcs->fb_create(dev, file_priv, r);
if (IS_ERR(fb)) { if (IS_ERR(fb)) {
DRM_DEBUG_KMS("could not create framebuffer\n"); DRM_DEBUG_KMS("could not create framebuffer\n");
return PTR_ERR(fb); return fb;
} }
mutex_lock(&file_priv->fbs_lock); mutex_lock(&file_priv->fbs_lock);
...@@ -2885,8 +2871,37 @@ int drm_mode_addfb2(struct drm_device *dev, ...@@ -2885,8 +2871,37 @@ int drm_mode_addfb2(struct drm_device *dev,
DRM_DEBUG_KMS("[FB:%d]\n", fb->base.id); DRM_DEBUG_KMS("[FB:%d]\n", fb->base.id);
mutex_unlock(&file_priv->fbs_lock); mutex_unlock(&file_priv->fbs_lock);
return fb;
}
return ret; /**
* drm_mode_addfb2 - add an FB to the graphics configuration
* @dev: drm device for the ioctl
* @data: data pointer for the ioctl
* @file_priv: drm file for the ioctl call
*
* Add a new FB to the specified CRTC, given a user request with format. This is
* the 2nd version of the addfb ioctl, which supports multi-planar framebuffers
* and uses fourcc codes as pixel format specifiers.
*
* Called by the user via ioctl.
*
* Returns:
* Zero on success, errno on failure.
*/
int drm_mode_addfb2(struct drm_device *dev,
void *data, struct drm_file *file_priv)
{
struct drm_framebuffer *fb;
if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;
fb = add_framebuffer_internal(dev, data, file_priv);
if (IS_ERR(fb))
return PTR_ERR(fb);
return 0;
} }
/** /**
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册