diff options
Diffstat (limited to 'drivers/gpu/drm/drm_crtc.c')
-rw-r--r-- | drivers/gpu/drm/drm_crtc.c | 48 |
1 files changed, 20 insertions, 28 deletions
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 6b6b07ff720b..679b10e34fb5 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c | |||
@@ -43,9 +43,10 @@ | |||
43 | #include "drm_crtc_internal.h" | 43 | #include "drm_crtc_internal.h" |
44 | #include "drm_internal.h" | 44 | #include "drm_internal.h" |
45 | 45 | ||
46 | static struct drm_framebuffer *add_framebuffer_internal(struct drm_device *dev, | 46 | static struct drm_framebuffer * |
47 | struct drm_mode_fb_cmd2 *r, | 47 | internal_framebuffer_create(struct drm_device *dev, |
48 | struct drm_file *file_priv); | 48 | struct drm_mode_fb_cmd2 *r, |
49 | struct drm_file *file_priv); | ||
49 | 50 | ||
50 | /* Avoid boilerplate. I'm tired of typing. */ | 51 | /* Avoid boilerplate. I'm tired of typing. */ |
51 | #define DRM_ENUM_NAME_FN(fnname, list) \ | 52 | #define DRM_ENUM_NAME_FN(fnname, list) \ |
@@ -524,17 +525,6 @@ void drm_framebuffer_reference(struct drm_framebuffer *fb) | |||
524 | } | 525 | } |
525 | EXPORT_SYMBOL(drm_framebuffer_reference); | 526 | EXPORT_SYMBOL(drm_framebuffer_reference); |
526 | 527 | ||
527 | static void drm_framebuffer_free_bug(struct kref *kref) | ||
528 | { | ||
529 | BUG(); | ||
530 | } | ||
531 | |||
532 | static void __drm_framebuffer_unreference(struct drm_framebuffer *fb) | ||
533 | { | ||
534 | DRM_DEBUG("%p: FB ID: %d (%d)\n", fb, fb->base.id, atomic_read(&fb->refcount.refcount)); | ||
535 | kref_put(&fb->refcount, drm_framebuffer_free_bug); | ||
536 | } | ||
537 | |||
538 | /** | 528 | /** |
539 | * drm_framebuffer_unregister_private - unregister a private fb from the lookup idr | 529 | * drm_framebuffer_unregister_private - unregister a private fb from the lookup idr |
540 | * @fb: fb to unregister | 530 | * @fb: fb to unregister |
@@ -1319,7 +1309,7 @@ void drm_plane_force_disable(struct drm_plane *plane) | |||
1319 | return; | 1309 | return; |
1320 | } | 1310 | } |
1321 | /* disconnect the plane from the fb and crtc: */ | 1311 | /* disconnect the plane from the fb and crtc: */ |
1322 | __drm_framebuffer_unreference(plane->old_fb); | 1312 | drm_framebuffer_unreference(plane->old_fb); |
1323 | plane->old_fb = NULL; | 1313 | plane->old_fb = NULL; |
1324 | plane->fb = NULL; | 1314 | plane->fb = NULL; |
1325 | plane->crtc = NULL; | 1315 | plane->crtc = NULL; |
@@ -2908,13 +2898,11 @@ static int drm_mode_cursor_universal(struct drm_crtc *crtc, | |||
2908 | */ | 2898 | */ |
2909 | if (req->flags & DRM_MODE_CURSOR_BO) { | 2899 | if (req->flags & DRM_MODE_CURSOR_BO) { |
2910 | if (req->handle) { | 2900 | if (req->handle) { |
2911 | fb = add_framebuffer_internal(dev, &fbreq, file_priv); | 2901 | fb = internal_framebuffer_create(dev, &fbreq, file_priv); |
2912 | if (IS_ERR(fb)) { | 2902 | if (IS_ERR(fb)) { |
2913 | DRM_DEBUG_KMS("failed to wrap cursor buffer in drm framebuffer\n"); | 2903 | DRM_DEBUG_KMS("failed to wrap cursor buffer in drm framebuffer\n"); |
2914 | return PTR_ERR(fb); | 2904 | return PTR_ERR(fb); |
2915 | } | 2905 | } |
2916 | |||
2917 | drm_framebuffer_reference(fb); | ||
2918 | } else { | 2906 | } else { |
2919 | fb = NULL; | 2907 | fb = NULL; |
2920 | } | 2908 | } |
@@ -3267,9 +3255,10 @@ static int framebuffer_check(const struct drm_mode_fb_cmd2 *r) | |||
3267 | return 0; | 3255 | return 0; |
3268 | } | 3256 | } |
3269 | 3257 | ||
3270 | static struct drm_framebuffer *add_framebuffer_internal(struct drm_device *dev, | 3258 | static struct drm_framebuffer * |
3271 | struct drm_mode_fb_cmd2 *r, | 3259 | internal_framebuffer_create(struct drm_device *dev, |
3272 | struct drm_file *file_priv) | 3260 | struct drm_mode_fb_cmd2 *r, |
3261 | struct drm_file *file_priv) | ||
3273 | { | 3262 | { |
3274 | struct drm_mode_config *config = &dev->mode_config; | 3263 | struct drm_mode_config *config = &dev->mode_config; |
3275 | struct drm_framebuffer *fb; | 3264 | struct drm_framebuffer *fb; |
@@ -3301,12 +3290,6 @@ static struct drm_framebuffer *add_framebuffer_internal(struct drm_device *dev, | |||
3301 | return fb; | 3290 | return fb; |
3302 | } | 3291 | } |
3303 | 3292 | ||
3304 | mutex_lock(&file_priv->fbs_lock); | ||
3305 | r->fb_id = fb->base.id; | ||
3306 | list_add(&fb->filp_head, &file_priv->fbs); | ||
3307 | DRM_DEBUG_KMS("[FB:%d]\n", fb->base.id); | ||
3308 | mutex_unlock(&file_priv->fbs_lock); | ||
3309 | |||
3310 | return fb; | 3293 | return fb; |
3311 | } | 3294 | } |
3312 | 3295 | ||
@@ -3328,15 +3311,24 @@ static struct drm_framebuffer *add_framebuffer_internal(struct drm_device *dev, | |||
3328 | int drm_mode_addfb2(struct drm_device *dev, | 3311 | int drm_mode_addfb2(struct drm_device *dev, |
3329 | void *data, struct drm_file *file_priv) | 3312 | void *data, struct drm_file *file_priv) |
3330 | { | 3313 | { |
3314 | struct drm_mode_fb_cmd2 *r = data; | ||
3331 | struct drm_framebuffer *fb; | 3315 | struct drm_framebuffer *fb; |
3332 | 3316 | ||
3333 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) | 3317 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
3334 | return -EINVAL; | 3318 | return -EINVAL; |
3335 | 3319 | ||
3336 | fb = add_framebuffer_internal(dev, data, file_priv); | 3320 | fb = internal_framebuffer_create(dev, r, file_priv); |
3337 | if (IS_ERR(fb)) | 3321 | if (IS_ERR(fb)) |
3338 | return PTR_ERR(fb); | 3322 | return PTR_ERR(fb); |
3339 | 3323 | ||
3324 | /* Transfer ownership to the filp for reaping on close */ | ||
3325 | |||
3326 | DRM_DEBUG_KMS("[FB:%d]\n", fb->base.id); | ||
3327 | mutex_lock(&file_priv->fbs_lock); | ||
3328 | r->fb_id = fb->base.id; | ||
3329 | list_add(&fb->filp_head, &file_priv->fbs); | ||
3330 | mutex_unlock(&file_priv->fbs_lock); | ||
3331 | |||
3340 | return 0; | 3332 | return 0; |
3341 | } | 3333 | } |
3342 | 3334 | ||