info = drm_fb_helper_alloc_fbi(helper);
        if (IS_ERR(info)) {
                ret = PTR_ERR(info);
-               goto out_unref;
+               goto out;
        }
 
        info->par = rfbdev;
        ret = amdgpu_framebuffer_init(adev->ddev, &rfbdev->rfb, &mode_cmd, gobj);
        if (ret) {
                DRM_ERROR("failed to initialize framebuffer %d\n", ret);
-               goto out_destroy_fbi;
+               goto out;
        }
 
        fb = &rfbdev->rfb.base;
 
        if (info->screen_base == NULL) {
                ret = -ENOSPC;
-               goto out_destroy_fbi;
+               goto out;
        }
 
        DRM_INFO("fb mappable at 0x%lX\n",  info->fix.smem_start);
        vga_switcheroo_client_fb_set(adev->ddev->pdev, info);
        return 0;
 
-out_destroy_fbi:
-       drm_fb_helper_release_fbi(helper);
-out_unref:
+out:
        if (abo) {
 
        }
        struct amdgpu_framebuffer *rfb = &rfbdev->rfb;
 
        drm_fb_helper_unregister_fbi(&rfbdev->helper);
-       drm_fb_helper_release_fbi(&rfbdev->helper);
 
        if (rfb->obj) {
                amdgpufb_destroy_pinned_object(rfb->obj);
 
 
        return 0;
  err_fb_setup:
-       drm_fb_helper_release_fbi(fbh);
        drm_fb_helper_fini(fbh);
  err_fb_helper:
        priv->fbdev = NULL;
 
        if (fbh) {
                drm_fb_helper_unregister_fbi(fbh);
-               drm_fb_helper_release_fbi(fbh);
 
                drm_fb_helper_fini(fbh);
 
 
        info = drm_fb_helper_alloc_fbi(helper);
        if (IS_ERR(info)) {
                ret = PTR_ERR(info);
-               goto err_free_vram;
+               goto out;
        }
        info->par = afbdev;
 
        ret = ast_framebuffer_init(dev, &afbdev->afb, &mode_cmd, gobj);
        if (ret)
-               goto err_release_fbi;
+               goto out;
 
        afbdev->sysram = sysram;
        afbdev->size = size;
 
        return 0;
 
-err_release_fbi:
-       drm_fb_helper_release_fbi(helper);
-err_free_vram:
+out:
        vfree(sysram);
        return ret;
 }
        struct ast_framebuffer *afb = &afbdev->afb;
 
        drm_fb_helper_unregister_fbi(&afbdev->helper);
-       drm_fb_helper_release_fbi(&afbdev->helper);
 
        if (afb->obj) {
                drm_gem_object_unreference_unlocked(afb->obj);
 
        info->par = &bochs->fb.helper;
 
        ret = bochs_framebuffer_init(bochs->dev, &bochs->fb.gfb, &mode_cmd, gobj);
-       if (ret) {
-               drm_fb_helper_release_fbi(helper);
+       if (ret)
                return ret;
-       }
 
        bochs->fb.size = size;
 
        DRM_DEBUG_DRIVER("\n");
 
        drm_fb_helper_unregister_fbi(&bochs->fb.helper);
-       drm_fb_helper_release_fbi(&bochs->fb.helper);
 
        if (gfb->obj) {
                drm_gem_object_unreference_unlocked(gfb->obj);
 
        struct cirrus_framebuffer *gfb = &gfbdev->gfb;
 
        drm_fb_helper_unregister_fbi(&gfbdev->helper);
-       drm_fb_helper_release_fbi(&gfbdev->helper);
 
        if (gfb->obj) {
                drm_gem_object_unreference_unlocked(gfb->obj);
 
 err_cma_destroy:
        drm_framebuffer_remove(&fbdev_cma->fb->fb);
 err_fb_info_destroy:
-       drm_fb_helper_release_fbi(helper);
+       drm_fb_helper_fini(helper);
 err_gem_free_object:
        drm_gem_object_unreference_unlocked(&obj->base);
        return ret;
        drm_fb_helper_unregister_fbi(&fbdev_cma->fb_helper);
        if (fbdev_cma->fb_helper.fbdev)
                drm_fbdev_cma_defio_fini(fbdev_cma->fb_helper.fbdev);
-       drm_fb_helper_release_fbi(&fbdev_cma->fb_helper);
 
        if (fbdev_cma->fb)
                drm_framebuffer_remove(&fbdev_cma->fb->fb);
 
  * @fb_helper: driver-allocated fbdev helper
  *
  * A helper to alloc fb_info and the members cmap and apertures. Called
- * by the driver within the fb_probe fb_helper callback function.
+ * by the driver within the fb_probe fb_helper callback function. Drivers do not
+ * need to release the allocated fb_info structure themselves, this is
+ * automatically done when calling drm_fb_helper_fini().
  *
  * RETURNS:
  * fb_info pointer if things went okay, pointer containing error code
 }
 EXPORT_SYMBOL(drm_fb_helper_unregister_fbi);
 
-/**
- * drm_fb_helper_release_fbi - dealloc fb_info and its members
- * @fb_helper: driver-allocated fbdev helper
- *
- * A helper to free memory taken by fb_info and the members cmap and
- * apertures
- */
-void drm_fb_helper_release_fbi(struct drm_fb_helper *fb_helper)
-{
-       if (fb_helper) {
-               struct fb_info *info = fb_helper->fbdev;
-
-               if (info) {
-                       if (info->cmap.len)
-                               fb_dealloc_cmap(&info->cmap);
-                       framebuffer_release(info);
-               }
-
-               fb_helper->fbdev = NULL;
-       }
-}
-EXPORT_SYMBOL(drm_fb_helper_release_fbi);
-
 /**
  * drm_fb_helper_fini - finialize a &struct drm_fb_helper
  * @fb_helper: driver-allocated fbdev helper
  */
 void drm_fb_helper_fini(struct drm_fb_helper *fb_helper)
 {
-       if (!drm_fbdev_emulation)
+       struct fb_info *info;
+
+       if (!drm_fbdev_emulation || !fb_helper)
                return;
 
+       info = fb_helper->fbdev;
+       if (info) {
+               if (info->cmap.len)
+                       fb_dealloc_cmap(&info->cmap);
+               framebuffer_release(info);
+       }
+       fb_helper->fbdev = NULL;
+
        mutex_lock(&kernel_fb_helper_lock);
        if (!list_empty(&fb_helper->kernel_fb_list)) {
                list_del(&fb_helper->kernel_fb_list);
 
                                VM_MAP, pgprot_writecombine(PAGE_KERNEL));
        if (!exynos_gem->kvaddr) {
                DRM_ERROR("failed to map pages to kernel space.\n");
-               drm_fb_helper_release_fbi(helper);
                return -EIO;
        }
 
        }
 
        drm_fb_helper_unregister_fbi(fb_helper);
-       drm_fb_helper_release_fbi(fb_helper);
 
        drm_fb_helper_fini(fb_helper);
 }
 
        info = drm_fb_helper_alloc_fbi(&fbdev->psb_fb_helper);
        if (IS_ERR(info)) {
                ret = PTR_ERR(info);
-               goto err_free_range;
+               goto out;
        }
        info->par = fbdev;
 
 
        ret = psb_framebuffer_init(dev, psbfb, &mode_cmd, backing);
        if (ret)
-               goto err_release;
+               goto out;
 
        fb = &psbfb->base;
        psbfb->fbdev = info;
                                        psbfb->base.width, psbfb->base.height);
 
        return 0;
-err_release:
-       drm_fb_helper_release_fbi(&fbdev->psb_fb_helper);
-err_free_range:
+out:
        psb_gtt_free_range(dev, backing);
        return ret;
 }
        struct psb_framebuffer *psbfb = &fbdev->pfb;
 
        drm_fb_helper_unregister_fbi(&fbdev->psb_fb_helper);
-       drm_fb_helper_release_fbi(&fbdev->psb_fb_helper);
 
        drm_fb_helper_fini(&fbdev->psb_fb_helper);
        drm_framebuffer_unregister_private(&psbfb->base);
 
        return 0;
 
 out_release_fbi:
-       drm_fb_helper_release_fbi(helper);
        ret1 = ttm_bo_reserve(&bo->bo, true, false, NULL);
        if (ret1) {
                DRM_ERROR("failed to rsv ttm_bo when release fbi: %d\n", ret1);
        struct drm_fb_helper *fbh = &fbdev->helper;
 
        drm_fb_helper_unregister_fbi(fbh);
-       drm_fb_helper_release_fbi(fbh);
 
        drm_fb_helper_fini(fbh);
 
 
        if (IS_ERR(vaddr)) {
                DRM_ERROR("Failed to remap framebuffer into virtual memory\n");
                ret = PTR_ERR(vaddr);
-               goto out_destroy_fbi;
+               goto out_unpin;
        }
        info->screen_base = vaddr;
        info->screen_size = vma->node.size;
        vga_switcheroo_client_fb_set(pdev, info);
        return 0;
 
-out_destroy_fbi:
-       drm_fb_helper_release_fbi(helper);
 out_unpin:
        intel_unpin_fb_vma(vma);
 out_unlock:
         */
 
        drm_fb_helper_unregister_fbi(&ifbdev->helper);
-       drm_fb_helper_release_fbi(&ifbdev->helper);
 
        drm_fb_helper_fini(&ifbdev->helper);
 
 
 
        ret = mgag200_framebuffer_init(dev, &mfbdev->mfb, &mode_cmd, gobj);
        if (ret)
-               goto err_framebuffer_init;
+               goto err_alloc_fbi;
 
        mfbdev->sysram = sysram;
        mfbdev->size = size;
 
        return 0;
 
-err_framebuffer_init:
-       drm_fb_helper_release_fbi(helper);
 err_alloc_fbi:
        vfree(sysram);
 err_sysram:
        struct mga_framebuffer *mfb = &mfbdev->mfb;
 
        drm_fb_helper_unregister_fbi(&mfbdev->helper);
-       drm_fb_helper_release_fbi(&mfbdev->helper);
 
        if (mfb->obj) {
                drm_gem_object_unreference_unlocked(mfb->obj);
 
        DBG();
 
        drm_fb_helper_unregister_fbi(helper);
-       drm_fb_helper_release_fbi(helper);
 
        drm_fb_helper_fini(helper);
 
 
        struct nouveau_framebuffer *nouveau_fb = nouveau_framebuffer(fbcon->helper.fb);
 
        drm_fb_helper_unregister_fbi(&fbcon->helper);
-       drm_fb_helper_release_fbi(&fbcon->helper);
        drm_fb_helper_fini(&fbcon->helper);
 
        if (nouveau_fb->nvbo) {
 
 fail:
 
        if (ret) {
-
-               drm_fb_helper_release_fbi(helper);
-
                if (fb)
                        drm_framebuffer_remove(fb);
        }
        DBG();
 
        drm_fb_helper_unregister_fbi(helper);
-       drm_fb_helper_release_fbi(helper);
 
        drm_fb_helper_fini(helper);
 
 
 
        if (info->screen_base == NULL) {
                ret = -ENOSPC;
-               goto out_destroy_fbi;
+               goto out_unref;
        }
 
 #ifdef CONFIG_DRM_FBDEV_EMULATION
                 fb->format->depth, fb->pitches[0], fb->width, fb->height);
        return 0;
 
-out_destroy_fbi:
-       drm_fb_helper_release_fbi(&qfbdev->helper);
 out_unref:
        if (qbo) {
                ret = qxl_bo_reserve(qbo, false);
        struct qxl_framebuffer *qfb = &qfbdev->qfb;
 
        drm_fb_helper_unregister_fbi(&qfbdev->helper);
-       drm_fb_helper_release_fbi(&qfbdev->helper);
 
        if (qfb->obj) {
                qxlfb_destroy_pinned_object(qfb->obj);
 
        info = drm_fb_helper_alloc_fbi(helper);
        if (IS_ERR(info)) {
                ret = PTR_ERR(info);
-               goto out_unref;
+               goto out;
        }
 
        info->par = rfbdev;
        ret = radeon_framebuffer_init(rdev->ddev, &rfbdev->rfb, &mode_cmd, gobj);
        if (ret) {
                DRM_ERROR("failed to initialize framebuffer %d\n", ret);
-               goto out_destroy_fbi;
+               goto out;
        }
 
        fb = &rfbdev->rfb.base;
 
        if (info->screen_base == NULL) {
                ret = -ENOSPC;
-               goto out_destroy_fbi;
+               goto out;
        }
 
        DRM_INFO("fb mappable at 0x%lX\n",  info->fix.smem_start);
        vga_switcheroo_client_fb_set(rdev->ddev->pdev, info);
        return 0;
 
-out_destroy_fbi:
-       drm_fb_helper_release_fbi(helper);
-out_unref:
+out:
        if (rbo) {
 
        }
        struct radeon_framebuffer *rfb = &rfbdev->rfb;
 
        drm_fb_helper_unregister_fbi(&rfbdev->helper);
-       drm_fb_helper_release_fbi(&rfbdev->helper);
 
        if (rfb->obj) {
                radeonfb_destroy_pinned_object(rfb->obj);
 
        if (IS_ERR(fbi)) {
                dev_err(dev->dev, "Failed to create framebuffer info.\n");
                ret = PTR_ERR(fbi);
-               goto err_rockchip_gem_free_object;
+               goto out;
        }
 
        helper->fb = rockchip_drm_framebuffer_init(dev, &mode_cmd,
        if (IS_ERR(helper->fb)) {
                dev_err(dev->dev, "Failed to allocate DRM framebuffer.\n");
                ret = PTR_ERR(helper->fb);
-               goto err_release_fbi;
+               goto out;
        }
 
        fbi->par = helper;
 
        return 0;
 
-err_release_fbi:
-       drm_fb_helper_release_fbi(helper);
-err_rockchip_gem_free_object:
+out:
        rockchip_gem_free_object(&rk_obj->base);
        return ret;
 }
        helper = &private->fbdev_helper;
 
        drm_fb_helper_unregister_fbi(helper);
-       drm_fb_helper_release_fbi(helper);
 
        if (helper->fb)
                drm_framebuffer_unreference(helper->fb);
 
                dev_err(drm->dev, "failed to allocate DRM framebuffer: %d\n",
                        err);
                drm_gem_object_unreference_unlocked(&bo->gem);
-               goto release;
+               return PTR_ERR(fbdev->fb);
        }
 
        fb = &fbdev->fb->base;
 
 destroy:
        drm_framebuffer_remove(fb);
-release:
-       drm_fb_helper_release_fbi(helper);
        return err;
 }
 
 static void tegra_fbdev_exit(struct tegra_fbdev *fbdev)
 {
        drm_fb_helper_unregister_fbi(&fbdev->base);
-       drm_fb_helper_release_fbi(&fbdev->base);
 
        if (fbdev->fb)
                drm_framebuffer_remove(&fbdev->fb->base);
 
 
        ret = udl_framebuffer_init(dev, &ufbdev->ufb, &mode_cmd, obj);
        if (ret)
-               goto out_destroy_fbi;
+               goto out_gfree;
 
        fb = &ufbdev->ufb.base;
 
                      ufbdev->ufb.obj->vmapping);
 
        return ret;
-out_destroy_fbi:
-       drm_fb_helper_release_fbi(helper);
 out_gfree:
        drm_gem_object_unreference_unlocked(&ufbdev->ufb.obj->base);
 out:
                              struct udl_fbdev *ufbdev)
 {
        drm_fb_helper_unregister_fbi(&ufbdev->helper);
-       drm_fb_helper_release_fbi(&ufbdev->helper);
        drm_fb_helper_fini(&ufbdev->helper);
        drm_framebuffer_unregister_private(&ufbdev->ufb.base);
        drm_framebuffer_cleanup(&ufbdev->ufb.base);
 
        ret = virtio_gpu_framebuffer_init(dev, &vfbdev->vgfb,
                                          &mode_cmd, &obj->gem_base);
        if (ret)
-               goto err_fb_init;
+               goto err_fb_alloc;
 
        fb = &vfbdev->vgfb.base;
 
        info->fix.mmio_len = 0;
        return 0;
 
-err_fb_init:
-       drm_fb_helper_release_fbi(helper);
 err_fb_alloc:
        virtio_gpu_cmd_resource_inval_backing(vgdev, resid);
 err_obj_attach:
        struct virtio_gpu_framebuffer *vgfb = &vgfbdev->vgfb;
 
        drm_fb_helper_unregister_fbi(&vgfbdev->helper);
-       drm_fb_helper_release_fbi(&vgfbdev->helper);
 
        if (vgfb->obj)
                vgfb->obj = NULL;
 
 
 struct fb_info *drm_fb_helper_alloc_fbi(struct drm_fb_helper *fb_helper);
 void drm_fb_helper_unregister_fbi(struct drm_fb_helper *fb_helper);
-void drm_fb_helper_release_fbi(struct drm_fb_helper *fb_helper);
 void drm_fb_helper_fill_var(struct fb_info *info, struct drm_fb_helper *fb_helper,
                            uint32_t fb_width, uint32_t fb_height);
 void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch,
 static inline void drm_fb_helper_unregister_fbi(struct drm_fb_helper *fb_helper)
 {
 }
-static inline void drm_fb_helper_release_fbi(struct drm_fb_helper *fb_helper)
-{
-}
 
 static inline void drm_fb_helper_fill_var(struct fb_info *info,
                                          struct drm_fb_helper *fb_helper,