aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_crtc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/drm_crtc.c')
-rw-r--r--drivers/gpu/drm/drm_crtc.c48
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
46static struct drm_framebuffer *add_framebuffer_internal(struct drm_device *dev, 46static struct drm_framebuffer *
47 struct drm_mode_fb_cmd2 *r, 47internal_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}
525EXPORT_SYMBOL(drm_framebuffer_reference); 526EXPORT_SYMBOL(drm_framebuffer_reference);
526 527
527static void drm_framebuffer_free_bug(struct kref *kref)
528{
529 BUG();
530}
531
532static 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
3270static struct drm_framebuffer *add_framebuffer_internal(struct drm_device *dev, 3258static struct drm_framebuffer *
3271 struct drm_mode_fb_cmd2 *r, 3259internal_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,
3328int drm_mode_addfb2(struct drm_device *dev, 3311int 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