diff options
-rw-r--r-- | drivers/gpu/drm/ast/ast_fb.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/cirrus/cirrus_fbdev.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_crtc.c | 31 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_fb_cma_helper.c | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_fbdev.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/gma500/framebuffer.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_fb.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/mgag200/mgag200_fb.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_fbcon.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_fb.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/udl/udl_fb.c | 1 | ||||
-rw-r--r-- | drivers/staging/omapdrm/omap_fbdev.c | 8 | ||||
-rw-r--r-- | include/drm/drm_crtc.h | 1 |
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 | |||
71 | EXPORT_SYMBOL(drm_modeset_unlock_all); | 72 | EXPORT_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) | |||
430 | EXPORT_SYMBOL(drm_framebuffer_reference); | 431 | EXPORT_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 | */ | ||
442 | void drm_framebuffer_unregister_private(struct drm_framebuffer *fb) | ||
443 | { | ||
444 | } | ||
445 | EXPORT_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 | */ |
439 | void drm_framebuffer_cleanup(struct drm_framebuffer *fb) | 463 | void 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 | */ |
465 | void drm_framebuffer_remove(struct drm_framebuffer *fb) | 490 | void 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 | ||
268 | err_drm_fb_cma_destroy: | 268 | err_drm_fb_cma_destroy: |
269 | drm_framebuffer_unregister_private(fb); | ||
269 | drm_fb_cma_destroy(fb); | 270 | drm_fb_cma_destroy(fb); |
270 | err_framebuffer_release: | 271 | err_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); | |||
964 | extern void drm_framebuffer_reference(struct drm_framebuffer *fb); | 964 | extern void drm_framebuffer_reference(struct drm_framebuffer *fb); |
965 | extern void drm_framebuffer_remove(struct drm_framebuffer *fb); | 965 | extern void drm_framebuffer_remove(struct drm_framebuffer *fb); |
966 | extern void drm_framebuffer_cleanup(struct drm_framebuffer *fb); | 966 | extern void drm_framebuffer_cleanup(struct drm_framebuffer *fb); |
967 | extern void drm_framebuffer_unregister_private(struct drm_framebuffer *fb); | ||
967 | extern int drmfb_probe(struct drm_device *dev, struct drm_crtc *crtc); | 968 | extern int drmfb_probe(struct drm_device *dev, struct drm_crtc *crtc); |
968 | extern int drmfb_remove(struct drm_device *dev, struct drm_framebuffer *fb); | 969 | extern int drmfb_remove(struct drm_device *dev, struct drm_framebuffer *fb); |
969 | extern void drm_crtc_probe_connector_modes(struct drm_device *dev, int maxX, int maxY); | 970 | extern void drm_crtc_probe_connector_modes(struct drm_device *dev, int maxX, int maxY); |