aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/ast/ast_fb.c1
-rw-r--r--drivers/gpu/drm/cirrus/cirrus_fbdev.c1
-rw-r--r--drivers/gpu/drm/drm_crtc.c31
-rw-r--r--drivers/gpu/drm/drm_fb_cma_helper.c5
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fbdev.c4
-rw-r--r--drivers/gpu/drm/gma500/framebuffer.c1
-rw-r--r--drivers/gpu/drm/i915/intel_display.c6
-rw-r--r--drivers/gpu/drm/i915/intel_fb.c1
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_fb.c1
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_fbcon.c1
-rw-r--r--drivers/gpu/drm/radeon/radeon_fb.c2
-rw-r--r--drivers/gpu/drm/udl/udl_fb.c1
-rw-r--r--drivers/staging/omapdrm/omap_fbdev.c8
-rw-r--r--include/drm/drm_crtc.h1
14 files changed, 55 insertions, 9 deletions
diff --git a/drivers/gpu/drm/ast/ast_fb.c b/drivers/gpu/drm/ast/ast_fb.c
index d9ec77959dff..3e6584b940dc 100644
--- a/drivers/gpu/drm/ast/ast_fb.c
+++ b/drivers/gpu/drm/ast/ast_fb.c
@@ -290,6 +290,7 @@ static void ast_fbdev_destroy(struct drm_device *dev,
290 drm_fb_helper_fini(&afbdev->helper); 290 drm_fb_helper_fini(&afbdev->helper);
291 291
292 vfree(afbdev->sysram); 292 vfree(afbdev->sysram);
293 drm_framebuffer_unregister_private(&afb->base);
293 drm_framebuffer_cleanup(&afb->base); 294 drm_framebuffer_cleanup(&afb->base);
294} 295}
295 296
diff --git a/drivers/gpu/drm/cirrus/cirrus_fbdev.c b/drivers/gpu/drm/cirrus/cirrus_fbdev.c
index 6c6b4c87d309..3daea0f638c3 100644
--- a/drivers/gpu/drm/cirrus/cirrus_fbdev.c
+++ b/drivers/gpu/drm/cirrus/cirrus_fbdev.c
@@ -258,6 +258,7 @@ static int cirrus_fbdev_destroy(struct drm_device *dev,
258 258
259 vfree(gfbdev->sysram); 259 vfree(gfbdev->sysram);
260 drm_fb_helper_fini(&gfbdev->helper); 260 drm_fb_helper_fini(&gfbdev->helper);
261 drm_framebuffer_unregister_private(&gfb->base);
261 drm_framebuffer_cleanup(&gfb->base); 262 drm_framebuffer_cleanup(&gfb->base);
262 263
263 return 0; 264 return 0;
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index f2ccda85309f..3eddfabeba96 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -68,6 +68,7 @@ void drm_modeset_unlock_all(struct drm_device *dev)
68 68
69 mutex_unlock(&dev->mode_config.mutex); 69 mutex_unlock(&dev->mode_config.mutex);
70} 70}
71
71EXPORT_SYMBOL(drm_modeset_unlock_all); 72EXPORT_SYMBOL(drm_modeset_unlock_all);
72 73
73/* Avoid boilerplate. I'm tired of typing. */ 74/* Avoid boilerplate. I'm tired of typing. */
@@ -430,11 +431,34 @@ void drm_framebuffer_reference(struct drm_framebuffer *fb)
430EXPORT_SYMBOL(drm_framebuffer_reference); 431EXPORT_SYMBOL(drm_framebuffer_reference);
431 432
432/** 433/**
434 * drm_framebuffer_unregister_private - unregister a private fb from the lookup idr
435 * @fb: fb to unregister
436 *
437 * Drivers need to call this when cleaning up driver-private framebuffers, e.g.
438 * those used for fbdev. Note that the caller must hold a reference of it's own,
439 * i.e. the object may not be destroyed through this call (since it'll lead to a
440 * locking inversion).
441 */
442void drm_framebuffer_unregister_private(struct drm_framebuffer *fb)
443{
444}
445EXPORT_SYMBOL(drm_framebuffer_unregister_private);
446
447/**
433 * drm_framebuffer_cleanup - remove a framebuffer object 448 * drm_framebuffer_cleanup - remove a framebuffer object
434 * @fb: framebuffer to remove 449 * @fb: framebuffer to remove
435 * 450 *
436 * Scans all the CRTCs in @dev's mode_config. If they're using @fb, removes 451 * Cleanup references to a user-created framebuffer. This function is intended
437 * it, setting it to NULL. 452 * to be used from the drivers ->destroy callback.
453 *
454 * Note that this function does not remove the fb from active usuage - if it is
455 * still used anywhere, hilarity can ensue since userspace could call getfb on
456 * the id and get back -EINVAL. Obviously no concern at driver unload time.
457 *
458 * Also, the framebuffer will not be removed from the lookup idr - for
459 * user-created framebuffers this will happen in in the rmfb ioctl. For
460 * driver-private objects (e.g. for fbdev) drivers need to explicitly call
461 * drm_framebuffer_unregister_private.
438 */ 462 */
439void drm_framebuffer_cleanup(struct drm_framebuffer *fb) 463void drm_framebuffer_cleanup(struct drm_framebuffer *fb)
440{ 464{
@@ -460,7 +484,8 @@ EXPORT_SYMBOL(drm_framebuffer_cleanup);
460 * @fb: framebuffer to remove 484 * @fb: framebuffer to remove
461 * 485 *
462 * Scans all the CRTCs and planes in @dev's mode_config. If they're 486 * Scans all the CRTCs and planes in @dev's mode_config. If they're
463 * using @fb, removes it, setting it to NULL. 487 * using @fb, removes it, setting it to NULL. Then drops the reference to the
488 * passed-in framebuffer.
464 */ 489 */
465void drm_framebuffer_remove(struct drm_framebuffer *fb) 490void drm_framebuffer_remove(struct drm_framebuffer *fb)
466{ 491{
diff --git a/drivers/gpu/drm/drm_fb_cma_helper.c b/drivers/gpu/drm/drm_fb_cma_helper.c
index e1e0cb0d531a..3742bc96421e 100644
--- a/drivers/gpu/drm/drm_fb_cma_helper.c
+++ b/drivers/gpu/drm/drm_fb_cma_helper.c
@@ -266,6 +266,7 @@ static int drm_fbdev_cma_create(struct drm_fb_helper *helper,
266 return 0; 266 return 0;
267 267
268err_drm_fb_cma_destroy: 268err_drm_fb_cma_destroy:
269 drm_framebuffer_unregister_private(fb);
269 drm_fb_cma_destroy(fb); 270 drm_fb_cma_destroy(fb);
270err_framebuffer_release: 271err_framebuffer_release:
271 framebuffer_release(fbi); 272 framebuffer_release(fbi);
@@ -370,8 +371,10 @@ void drm_fbdev_cma_fini(struct drm_fbdev_cma *fbdev_cma)
370 framebuffer_release(info); 371 framebuffer_release(info);
371 } 372 }
372 373
373 if (fbdev_cma->fb) 374 if (fbdev_cma->fb) {
375 drm_framebuffer_unregister_private(&fbdev_cma->fb->fb);
374 drm_fb_cma_destroy(&fbdev_cma->fb->fb); 376 drm_fb_cma_destroy(&fbdev_cma->fb->fb);
377 }
375 378
376 drm_fb_helper_fini(&fbdev_cma->fb_helper); 379 drm_fb_helper_fini(&fbdev_cma->fb_helper);
377 kfree(fbdev_cma); 380 kfree(fbdev_cma);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
index 71f867340a88..90d335cfb8c0 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
@@ -326,8 +326,10 @@ static void exynos_drm_fbdev_destroy(struct drm_device *dev,
326 /* release drm framebuffer and real buffer */ 326 /* release drm framebuffer and real buffer */
327 if (fb_helper->fb && fb_helper->fb->funcs) { 327 if (fb_helper->fb && fb_helper->fb->funcs) {
328 fb = fb_helper->fb; 328 fb = fb_helper->fb;
329 if (fb) 329 if (fb) {
330 drm_framebuffer_unregister_private(fb);
330 drm_framebuffer_remove(fb); 331 drm_framebuffer_remove(fb);
332 }
331 } 333 }
332 334
333 /* release linux framebuffer */ 335 /* release linux framebuffer */
diff --git a/drivers/gpu/drm/gma500/framebuffer.c b/drivers/gpu/drm/gma500/framebuffer.c
index 49800d2b79dd..c1ef37e2efdf 100644
--- a/drivers/gpu/drm/gma500/framebuffer.c
+++ b/drivers/gpu/drm/gma500/framebuffer.c
@@ -590,6 +590,7 @@ static int psb_fbdev_destroy(struct drm_device *dev, struct psb_fbdev *fbdev)
590 framebuffer_release(info); 590 framebuffer_release(info);
591 } 591 }
592 drm_fb_helper_fini(&fbdev->psb_fb_helper); 592 drm_fb_helper_fini(&fbdev->psb_fb_helper);
593 drm_framebuffer_unregister_private(&psbfb->base);
593 drm_framebuffer_cleanup(&psbfb->base); 594 drm_framebuffer_cleanup(&psbfb->base);
594 595
595 if (psbfb->gtt) 596 if (psbfb->gtt)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 26fa6a795afe..df51203dcebd 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -6789,8 +6789,10 @@ void intel_release_load_detect_pipe(struct drm_connector *connector,
6789 intel_encoder->new_crtc = NULL; 6789 intel_encoder->new_crtc = NULL;
6790 intel_set_mode(crtc, NULL, 0, 0, NULL); 6790 intel_set_mode(crtc, NULL, 0, 0, NULL);
6791 6791
6792 if (old->release_fb) 6792 if (old->release_fb) {
6793 old->release_fb->funcs->destroy(old->release_fb); 6793 drm_framebuffer_unregister_private(old->release_fb);
6794 drm_framebuffer_unreference(old->release_fb);
6795 }
6794 6796
6795 return; 6797 return;
6796 } 6798 }
diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c
index a9f7280f87fb..c7b8316137e9 100644
--- a/drivers/gpu/drm/i915/intel_fb.c
+++ b/drivers/gpu/drm/i915/intel_fb.c
@@ -212,6 +212,7 @@ static void intel_fbdev_destroy(struct drm_device *dev,
212 212
213 drm_fb_helper_fini(&ifbdev->helper); 213 drm_fb_helper_fini(&ifbdev->helper);
214 214
215 drm_framebuffer_unregister_private(&ifb->base);
215 drm_framebuffer_cleanup(&ifb->base); 216 drm_framebuffer_cleanup(&ifb->base);
216 if (ifb->obj) { 217 if (ifb->obj) {
217 drm_gem_object_unreference_unlocked(&ifb->obj->base); 218 drm_gem_object_unreference_unlocked(&ifb->obj->base);
diff --git a/drivers/gpu/drm/mgag200/mgag200_fb.c b/drivers/gpu/drm/mgag200/mgag200_fb.c
index 2f486481d79a..5c69b432f99a 100644
--- a/drivers/gpu/drm/mgag200/mgag200_fb.c
+++ b/drivers/gpu/drm/mgag200/mgag200_fb.c
@@ -247,6 +247,7 @@ static int mga_fbdev_destroy(struct drm_device *dev,
247 } 247 }
248 drm_fb_helper_fini(&mfbdev->helper); 248 drm_fb_helper_fini(&mfbdev->helper);
249 vfree(mfbdev->sysram); 249 vfree(mfbdev->sysram);
250 drm_framebuffer_unregister_private(&mfb->base);
250 drm_framebuffer_cleanup(&mfb->base); 251 drm_framebuffer_cleanup(&mfb->base);
251 252
252 return 0; 253 return 0;
diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
index 67a1a069de28..d4ecb4deb484 100644
--- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c
+++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
@@ -433,6 +433,7 @@ nouveau_fbcon_destroy(struct drm_device *dev, struct nouveau_fbdev *fbcon)
433 nouveau_fb->nvbo = NULL; 433 nouveau_fb->nvbo = NULL;
434 } 434 }
435 drm_fb_helper_fini(&fbcon->helper); 435 drm_fb_helper_fini(&fbcon->helper);
436 drm_framebuffer_unregister_private(&nouveau_fb->base);
436 drm_framebuffer_cleanup(&nouveau_fb->base); 437 drm_framebuffer_cleanup(&nouveau_fb->base);
437 return 0; 438 return 0;
438} 439}
diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c
index cc8489d8c6d1..515e5ee1f9ee 100644
--- a/drivers/gpu/drm/radeon/radeon_fb.c
+++ b/drivers/gpu/drm/radeon/radeon_fb.c
@@ -293,6 +293,7 @@ out_unref:
293 } 293 }
294 if (fb && ret) { 294 if (fb && ret) {
295 drm_gem_object_unreference(gobj); 295 drm_gem_object_unreference(gobj);
296 drm_framebuffer_unregister_private(fb);
296 drm_framebuffer_cleanup(fb); 297 drm_framebuffer_cleanup(fb);
297 kfree(fb); 298 kfree(fb);
298 } 299 }
@@ -339,6 +340,7 @@ static int radeon_fbdev_destroy(struct drm_device *dev, struct radeon_fbdev *rfb
339 rfb->obj = NULL; 340 rfb->obj = NULL;
340 } 341 }
341 drm_fb_helper_fini(&rfbdev->helper); 342 drm_fb_helper_fini(&rfbdev->helper);
343 drm_framebuffer_unregister_private(&rfb->base);
342 drm_framebuffer_cleanup(&rfb->base); 344 drm_framebuffer_cleanup(&rfb->base);
343 345
344 return 0; 346 return 0;
diff --git a/drivers/gpu/drm/udl/udl_fb.c b/drivers/gpu/drm/udl/udl_fb.c
index f8904b4e68de..caa84f1de9c1 100644
--- a/drivers/gpu/drm/udl/udl_fb.c
+++ b/drivers/gpu/drm/udl/udl_fb.c
@@ -555,6 +555,7 @@ static void udl_fbdev_destroy(struct drm_device *dev,
555 framebuffer_release(info); 555 framebuffer_release(info);
556 } 556 }
557 drm_fb_helper_fini(&ufbdev->helper); 557 drm_fb_helper_fini(&ufbdev->helper);
558 drm_framebuffer_unregister_private(&ufbdev->ufb.base);
558 drm_framebuffer_cleanup(&ufbdev->ufb.base); 559 drm_framebuffer_cleanup(&ufbdev->ufb.base);
559 drm_gem_object_unreference_unlocked(&ufbdev->ufb.obj->base); 560 drm_gem_object_unreference_unlocked(&ufbdev->ufb.obj->base);
560} 561}
diff --git a/drivers/staging/omapdrm/omap_fbdev.c b/drivers/staging/omapdrm/omap_fbdev.c
index 8a027bb77d97..2728e37e02be 100644
--- a/drivers/staging/omapdrm/omap_fbdev.c
+++ b/drivers/staging/omapdrm/omap_fbdev.c
@@ -275,8 +275,10 @@ fail:
275 if (ret) { 275 if (ret) {
276 if (fbi) 276 if (fbi)
277 framebuffer_release(fbi); 277 framebuffer_release(fbi);
278 if (fb) 278 if (fb) {
279 drm_framebuffer_unregister_private(fb);
279 drm_framebuffer_remove(fb); 280 drm_framebuffer_remove(fb);
281 }
280 } 282 }
281 283
282 return ret; 284 return ret;
@@ -400,8 +402,10 @@ void omap_fbdev_free(struct drm_device *dev)
400 fbdev = to_omap_fbdev(priv->fbdev); 402 fbdev = to_omap_fbdev(priv->fbdev);
401 403
402 /* this will free the backing object */ 404 /* this will free the backing object */
403 if (fbdev->fb) 405 if (fbdev->fb) {
406 drm_framebuffer_unregister_private(fbdev->fb);
404 drm_framebuffer_remove(fbdev->fb); 407 drm_framebuffer_remove(fbdev->fb);
408 }
405 409
406 kfree(fbdev); 410 kfree(fbdev);
407 411
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 7dc1b31059d4..66b2732f175a 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -964,6 +964,7 @@ extern void drm_framebuffer_unreference(struct drm_framebuffer *fb);
964extern void drm_framebuffer_reference(struct drm_framebuffer *fb); 964extern void drm_framebuffer_reference(struct drm_framebuffer *fb);
965extern void drm_framebuffer_remove(struct drm_framebuffer *fb); 965extern void drm_framebuffer_remove(struct drm_framebuffer *fb);
966extern void drm_framebuffer_cleanup(struct drm_framebuffer *fb); 966extern void drm_framebuffer_cleanup(struct drm_framebuffer *fb);
967extern void drm_framebuffer_unregister_private(struct drm_framebuffer *fb);
967extern int drmfb_probe(struct drm_device *dev, struct drm_crtc *crtc); 968extern int drmfb_probe(struct drm_device *dev, struct drm_crtc *crtc);
968extern int drmfb_remove(struct drm_device *dev, struct drm_framebuffer *fb); 969extern int drmfb_remove(struct drm_device *dev, struct drm_framebuffer *fb);
969extern void drm_crtc_probe_connector_modes(struct drm_device *dev, int maxX, int maxY); 970extern void drm_crtc_probe_connector_modes(struct drm_device *dev, int maxX, int maxY);