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.c52
1 files changed, 23 insertions, 29 deletions
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 6b6b07ff720b..b6f076b213bc 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;
@@ -2131,7 +2121,7 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
2131 connector = drm_connector_find(dev, out_resp->connector_id); 2121 connector = drm_connector_find(dev, out_resp->connector_id);
2132 if (!connector) { 2122 if (!connector) {
2133 ret = -ENOENT; 2123 ret = -ENOENT;
2134 goto out; 2124 goto out_unlock;
2135 } 2125 }
2136 2126
2137 for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) 2127 for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++)
@@ -2211,6 +2201,8 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
2211 2201
2212out: 2202out:
2213 drm_modeset_unlock(&dev->mode_config.connection_mutex); 2203 drm_modeset_unlock(&dev->mode_config.connection_mutex);
2204
2205out_unlock:
2214 mutex_unlock(&dev->mode_config.mutex); 2206 mutex_unlock(&dev->mode_config.mutex);
2215 2207
2216 return ret; 2208 return ret;
@@ -2908,13 +2900,11 @@ static int drm_mode_cursor_universal(struct drm_crtc *crtc,
2908 */ 2900 */
2909 if (req->flags & DRM_MODE_CURSOR_BO) { 2901 if (req->flags & DRM_MODE_CURSOR_BO) {
2910 if (req->handle) { 2902 if (req->handle) {
2911 fb = add_framebuffer_internal(dev, &fbreq, file_priv); 2903 fb = internal_framebuffer_create(dev, &fbreq, file_priv);
2912 if (IS_ERR(fb)) { 2904 if (IS_ERR(fb)) {
2913 DRM_DEBUG_KMS("failed to wrap cursor buffer in drm framebuffer\n"); 2905 DRM_DEBUG_KMS("failed to wrap cursor buffer in drm framebuffer\n");
2914 return PTR_ERR(fb); 2906 return PTR_ERR(fb);
2915 } 2907 }
2916
2917 drm_framebuffer_reference(fb);
2918 } else { 2908 } else {
2919 fb = NULL; 2909 fb = NULL;
2920 } 2910 }
@@ -3267,9 +3257,10 @@ static int framebuffer_check(const struct drm_mode_fb_cmd2 *r)
3267 return 0; 3257 return 0;
3268} 3258}
3269 3259
3270static struct drm_framebuffer *add_framebuffer_internal(struct drm_device *dev, 3260static struct drm_framebuffer *
3271 struct drm_mode_fb_cmd2 *r, 3261internal_framebuffer_create(struct drm_device *dev,
3272 struct drm_file *file_priv) 3262 struct drm_mode_fb_cmd2 *r,
3263 struct drm_file *file_priv)
3273{ 3264{
3274 struct drm_mode_config *config = &dev->mode_config; 3265 struct drm_mode_config *config = &dev->mode_config;
3275 struct drm_framebuffer *fb; 3266 struct drm_framebuffer *fb;
@@ -3301,12 +3292,6 @@ static struct drm_framebuffer *add_framebuffer_internal(struct drm_device *dev,
3301 return fb; 3292 return fb;
3302 } 3293 }
3303 3294
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; 3295 return fb;
3311} 3296}
3312 3297
@@ -3328,15 +3313,24 @@ static struct drm_framebuffer *add_framebuffer_internal(struct drm_device *dev,
3328int drm_mode_addfb2(struct drm_device *dev, 3313int drm_mode_addfb2(struct drm_device *dev,
3329 void *data, struct drm_file *file_priv) 3314 void *data, struct drm_file *file_priv)
3330{ 3315{
3316 struct drm_mode_fb_cmd2 *r = data;
3331 struct drm_framebuffer *fb; 3317 struct drm_framebuffer *fb;
3332 3318
3333 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 3319 if (!drm_core_check_feature(dev, DRIVER_MODESET))
3334 return -EINVAL; 3320 return -EINVAL;
3335 3321
3336 fb = add_framebuffer_internal(dev, data, file_priv); 3322 fb = internal_framebuffer_create(dev, r, file_priv);
3337 if (IS_ERR(fb)) 3323 if (IS_ERR(fb))
3338 return PTR_ERR(fb); 3324 return PTR_ERR(fb);
3339 3325
3326 /* Transfer ownership to the filp for reaping on close */
3327
3328 DRM_DEBUG_KMS("[FB:%d]\n", fb->base.id);
3329 mutex_lock(&file_priv->fbs_lock);
3330 r->fb_id = fb->base.id;
3331 list_add(&fb->filp_head, &file_priv->fbs);
3332 mutex_unlock(&file_priv->fbs_lock);
3333
3340 return 0; 3334 return 0;
3341} 3335}
3342 3336