Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

drm/fb-helper: Allocate and release fb_info in single place

Move the calls to drm_fb_helper_alloc_info() from drivers into a
single place in fbdev helpers. Allocates struct fb_info for a new
framebuffer device. Then call drm_fb_helper_single_fb_probe() to
create an fbdev screen buffer. Also release the instance on errors
by calling drm_fb_helper_release_info().

Simplifies the code and fixes the error cleanup for some of the
drivers.

Regular release of the struct fb_info instance still happens in
drm_fb_helper_fini() as before.

v2:
- remove error rollback in driver implementations (kernel test robot)
- initialize info in TTM implementation (kernel test robot)

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Acked-by: Christian König <christian.koenig@amd.com> # radeon
Acked-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> # msm
Acked-by: Javier Martinez Canillas <javierm@redhat.com>
Link: https://patch.msgid.link/20251027081245.80262-1-tzimmermann@suse.de

+26 -143
+1 -11
drivers/gpu/drm/armada/armada_fbdev.c
··· 44 44 struct drm_fb_helper_surface_size *sizes) 45 45 { 46 46 struct drm_device *dev = fbh->dev; 47 + struct fb_info *info = fbh->info; 47 48 struct drm_mode_fb_cmd2 mode; 48 49 struct armada_framebuffer *dfb; 49 50 struct armada_gem_object *obj; 50 - struct fb_info *info; 51 51 int size, ret; 52 52 void *ptr; 53 53 ··· 91 91 if (IS_ERR(dfb)) 92 92 return PTR_ERR(dfb); 93 93 94 - info = drm_fb_helper_alloc_info(fbh); 95 - if (IS_ERR(info)) { 96 - ret = PTR_ERR(info); 97 - goto err_fballoc; 98 - } 99 - 100 94 info->fbops = &armada_fb_ops; 101 95 info->fix.smem_start = obj->phys_addr; 102 96 info->fix.smem_len = obj->obj.size; ··· 106 112 (unsigned long long)obj->phys_addr); 107 113 108 114 return 0; 109 - 110 - err_fballoc: 111 - dfb->fb.funcs->destroy(&dfb->fb); 112 - return ret; 113 115 }
+12 -27
drivers/gpu/drm/drm_fb_helper.c
··· 459 459 } 460 460 EXPORT_SYMBOL(drm_fb_helper_init); 461 461 462 - /** 463 - * drm_fb_helper_alloc_info - allocate fb_info and some of its members 464 - * @fb_helper: driver-allocated fbdev helper 465 - * 466 - * A helper to alloc fb_info and the member cmap. Called by the driver 467 - * within the struct &drm_driver.fbdev_probe callback function. Drivers do 468 - * not need to release the allocated fb_info structure themselves, this is 469 - * automatically done when calling drm_fb_helper_fini(). 470 - * 471 - * RETURNS: 472 - * fb_info pointer if things went okay, pointer containing error code 473 - * otherwise 474 - */ 475 - struct fb_info *drm_fb_helper_alloc_info(struct drm_fb_helper *fb_helper) 462 + static struct fb_info *drm_fb_helper_alloc_info(struct drm_fb_helper *fb_helper) 476 463 { 477 464 struct device *dev = fb_helper->dev->dev; 478 465 struct fb_info *info; ··· 486 499 framebuffer_release(info); 487 500 return ERR_PTR(ret); 488 501 } 489 - EXPORT_SYMBOL(drm_fb_helper_alloc_info); 490 502 491 - /** 492 - * drm_fb_helper_release_info - release fb_info and its members 493 - * @fb_helper: driver-allocated fbdev helper 494 - * 495 - * A helper to release fb_info and the member cmap. Drivers do not 496 - * need to release the allocated fb_info structure themselves, this is 497 - * automatically done when calling drm_fb_helper_fini(). 498 - */ 499 - void drm_fb_helper_release_info(struct drm_fb_helper *fb_helper) 503 + static void drm_fb_helper_release_info(struct drm_fb_helper *fb_helper) 500 504 { 501 505 struct fb_info *info = fb_helper->info; 502 506 ··· 500 522 fb_dealloc_cmap(&info->cmap); 501 523 framebuffer_release(info); 502 524 } 503 - EXPORT_SYMBOL(drm_fb_helper_release_info); 504 525 505 526 /** 506 527 * drm_fb_helper_unregister_info - unregister fb_info framebuffer device ··· 1747 1770 height = dev->mode_config.max_height; 1748 1771 1749 1772 drm_client_modeset_probe(&fb_helper->client, width, height); 1773 + 1774 + info = drm_fb_helper_alloc_info(fb_helper); 1775 + if (IS_ERR(info)) 1776 + return PTR_ERR(info); 1777 + 1750 1778 ret = drm_fb_helper_single_fb_probe(fb_helper); 1751 1779 if (ret < 0) { 1752 1780 if (ret == -EAGAIN) { ··· 1760 1778 } 1761 1779 mutex_unlock(&fb_helper->lock); 1762 1780 1763 - return ret; 1781 + goto err_drm_fb_helper_release_info; 1764 1782 } 1765 1783 drm_setup_crtcs_fb(fb_helper); 1766 1784 1767 1785 fb_helper->deferred_setup = false; 1768 1786 1769 - info = fb_helper->info; 1770 1787 info->var.pixclock = 0; 1771 1788 1772 1789 /* Need to drop locks to avoid recursive deadlock in ··· 1785 1804 mutex_unlock(&kernel_fb_helper_lock); 1786 1805 1787 1806 return 0; 1807 + 1808 + err_drm_fb_helper_release_info: 1809 + drm_fb_helper_release_info(fb_helper); 1810 + return ret; 1788 1811 } 1789 1812 1790 1813 /**
+2 -10
drivers/gpu/drm/drm_fbdev_dma.c
··· 269 269 { 270 270 struct drm_client_dev *client = &fb_helper->client; 271 271 struct drm_device *dev = fb_helper->dev; 272 + struct fb_info *info = fb_helper->info; 272 273 struct drm_client_buffer *buffer; 273 274 struct drm_framebuffer *fb; 274 - struct fb_info *info; 275 275 u32 format; 276 276 struct iosys_map map; 277 277 int ret; ··· 301 301 fb_helper->buffer = buffer; 302 302 fb_helper->fb = fb; 303 303 304 - info = drm_fb_helper_alloc_info(fb_helper); 305 - if (IS_ERR(info)) { 306 - ret = PTR_ERR(info); 307 - goto err_drm_client_buffer_vunmap; 308 - } 309 - 310 304 drm_fb_helper_fill_info(info, fb_helper, sizes); 311 305 312 306 if (fb->funcs->dirty) ··· 308 314 else 309 315 ret = drm_fbdev_dma_driver_fbdev_probe_tail(fb_helper, sizes); 310 316 if (ret) 311 - goto err_drm_fb_helper_release_info; 317 + goto err_drm_client_buffer_vunmap; 312 318 313 319 return 0; 314 320 315 - err_drm_fb_helper_release_info: 316 - drm_fb_helper_release_info(fb_helper); 317 321 err_drm_client_buffer_vunmap: 318 322 fb_helper->fb = NULL; 319 323 fb_helper->buffer = NULL;
+2 -10
drivers/gpu/drm/drm_fbdev_shmem.c
··· 135 135 { 136 136 struct drm_client_dev *client = &fb_helper->client; 137 137 struct drm_device *dev = fb_helper->dev; 138 + struct fb_info *info = fb_helper->info; 138 139 struct drm_client_buffer *buffer; 139 140 struct drm_gem_shmem_object *shmem; 140 141 struct drm_framebuffer *fb; 141 - struct fb_info *info; 142 142 u32 format; 143 143 struct iosys_map map; 144 144 int ret; ··· 168 168 fb_helper->buffer = buffer; 169 169 fb_helper->fb = fb; 170 170 171 - info = drm_fb_helper_alloc_info(fb_helper); 172 - if (IS_ERR(info)) { 173 - ret = PTR_ERR(info); 174 - goto err_drm_client_buffer_vunmap; 175 - } 176 - 177 171 drm_fb_helper_fill_info(info, fb_helper, sizes); 178 172 179 173 info->fbops = &drm_fbdev_shmem_fb_ops; ··· 188 194 info->fbdefio = &fb_helper->fbdefio; 189 195 ret = fb_deferred_io_init(info); 190 196 if (ret) 191 - goto err_drm_fb_helper_release_info; 197 + goto err_drm_client_buffer_vunmap; 192 198 193 199 return 0; 194 200 195 - err_drm_fb_helper_release_info: 196 - drm_fb_helper_release_info(fb_helper); 197 201 err_drm_client_buffer_vunmap: 198 202 fb_helper->fb = NULL; 199 203 fb_helper->buffer = NULL;
+2 -10
drivers/gpu/drm/drm_fbdev_ttm.c
··· 174 174 { 175 175 struct drm_client_dev *client = &fb_helper->client; 176 176 struct drm_device *dev = fb_helper->dev; 177 + struct fb_info *info = fb_helper->info; 177 178 struct drm_client_buffer *buffer; 178 - struct fb_info *info; 179 179 size_t screen_size; 180 180 void *screen_buffer; 181 181 u32 format; ··· 203 203 goto err_drm_client_buffer_delete; 204 204 } 205 205 206 - info = drm_fb_helper_alloc_info(fb_helper); 207 - if (IS_ERR(info)) { 208 - ret = PTR_ERR(info); 209 - goto err_vfree; 210 - } 211 - 212 206 drm_fb_helper_fill_info(info, fb_helper, sizes); 213 207 214 208 info->fbops = &drm_fbdev_ttm_fb_ops; ··· 219 225 info->fbdefio = &fb_helper->fbdefio; 220 226 ret = fb_deferred_io_init(info); 221 227 if (ret) 222 - goto err_drm_fb_helper_release_info; 228 + goto err_vfree; 223 229 224 230 return 0; 225 231 226 - err_drm_fb_helper_release_info: 227 - drm_fb_helper_release_info(fb_helper); 228 232 err_vfree: 229 233 vfree(screen_buffer); 230 234 err_drm_client_buffer_delete:
+1 -8
drivers/gpu/drm/exynos/exynos_drm_fbdev.c
··· 58 58 struct drm_fb_helper_surface_size *sizes, 59 59 struct exynos_drm_gem *exynos_gem) 60 60 { 61 - struct fb_info *fbi; 61 + struct fb_info *fbi = helper->info; 62 62 struct drm_framebuffer *fb = helper->fb; 63 63 unsigned int size = fb->width * fb->height * fb->format->cpp[0]; 64 64 unsigned long offset; 65 - 66 - fbi = drm_fb_helper_alloc_info(helper); 67 - if (IS_ERR(fbi)) { 68 - DRM_DEV_ERROR(to_dma_dev(helper->dev), 69 - "failed to allocate fb info.\n"); 70 - return PTR_ERR(fbi); 71 - } 72 65 73 66 fbi->fbops = &exynos_drm_fb_ops; 74 67
+1 -11
drivers/gpu/drm/gma500/fbdev.c
··· 108 108 struct drm_device *dev = fb_helper->dev; 109 109 struct drm_psb_private *dev_priv = to_drm_psb_private(dev); 110 110 struct pci_dev *pdev = to_pci_dev(dev->dev); 111 - struct fb_info *info; 111 + struct fb_info *info = fb_helper->info; 112 112 struct drm_framebuffer *fb; 113 113 struct drm_mode_fb_cmd2 mode_cmd = { }; 114 114 int size; ··· 167 167 fb_helper->funcs = &psb_fbdev_fb_helper_funcs; 168 168 fb_helper->fb = fb; 169 169 170 - info = drm_fb_helper_alloc_info(fb_helper); 171 - if (IS_ERR(info)) { 172 - ret = PTR_ERR(info); 173 - goto err_drm_framebuffer_unregister_private; 174 - } 175 - 176 170 info->fbops = &psb_fbdev_fb_ops; 177 171 178 172 /* Accessed stolen memory directly */ ··· 190 196 191 197 return 0; 192 198 193 - err_drm_framebuffer_unregister_private: 194 - drm_framebuffer_unregister_private(fb); 195 - drm_framebuffer_cleanup(fb); 196 - kfree(fb); 197 199 err_drm_gem_object_put: 198 200 drm_gem_object_put(obj); 199 201 return ret;
+1 -8
drivers/gpu/drm/i915/display/intel_fbdev.c
··· 267 267 struct intel_display *display = to_intel_display(helper->dev); 268 268 struct intel_fbdev *ifbdev = to_intel_fbdev(helper); 269 269 struct intel_framebuffer *fb = ifbdev->fb; 270 + struct fb_info *info = helper->info; 270 271 struct ref_tracker *wakeref; 271 - struct fb_info *info; 272 272 struct i915_vma *vma; 273 273 unsigned long flags = 0; 274 274 bool prealloc = false; ··· 316 316 if (IS_ERR(vma)) { 317 317 ret = PTR_ERR(vma); 318 318 goto out_unlock; 319 - } 320 - 321 - info = drm_fb_helper_alloc_info(helper); 322 - if (IS_ERR(info)) { 323 - drm_err(display->drm, "Failed to allocate fb_info (%pe)\n", info); 324 - ret = PTR_ERR(info); 325 - goto out_unpin; 326 319 } 327 320 328 321 helper->funcs = &intel_fb_helper_funcs;
+1 -8
drivers/gpu/drm/msm/msm_fbdev.c
··· 91 91 { 92 92 struct drm_device *dev = helper->dev; 93 93 struct msm_drm_private *priv = dev->dev_private; 94 + struct fb_info *fbi = helper->info; 94 95 struct drm_framebuffer *fb = NULL; 95 96 struct drm_gem_object *bo; 96 - struct fb_info *fbi = NULL; 97 97 uint64_t paddr; 98 98 uint32_t format; 99 99 int ret, pitch; ··· 123 123 ret = msm_gem_get_and_pin_iova(bo, priv->kms->vm, &paddr); 124 124 if (ret) { 125 125 DRM_DEV_ERROR(dev->dev, "failed to get buffer obj iova: %d\n", ret); 126 - goto fail; 127 - } 128 - 129 - fbi = drm_fb_helper_alloc_info(helper); 130 - if (IS_ERR(fbi)) { 131 - DRM_DEV_ERROR(dev->dev, "failed to allocate fb info\n"); 132 - ret = PTR_ERR(fbi); 133 126 goto fail; 134 127 } 135 128
+1 -8
drivers/gpu/drm/omapdrm/omap_fbdev.c
··· 154 154 struct drm_device *dev = helper->dev; 155 155 struct omap_drm_private *priv = dev->dev_private; 156 156 struct omap_fbdev *fbdev = priv->fbdev; 157 + struct fb_info *fbi = helper->info; 157 158 struct drm_framebuffer *fb = NULL; 158 159 union omap_gem_size gsize; 159 - struct fb_info *fbi = NULL; 160 160 struct drm_mode_fb_cmd2 mode_cmd = {0}; 161 161 struct drm_gem_object *bo; 162 162 dma_addr_t dma_addr; ··· 222 222 if (ret) { 223 223 dev_err(dev->dev, "could not pin framebuffer\n"); 224 224 ret = -ENOMEM; 225 - goto fail; 226 - } 227 - 228 - fbi = drm_fb_helper_alloc_info(helper); 229 - if (IS_ERR(fbi)) { 230 - dev_err(dev->dev, "failed to allocate fb info\n"); 231 - ret = PTR_ERR(fbi); 232 225 goto fail; 233 226 } 234 227
+1 -12
drivers/gpu/drm/radeon/radeon_fbdev.c
··· 202 202 struct radeon_device *rdev = fb_helper->dev->dev_private; 203 203 const struct drm_format_info *format_info; 204 204 struct drm_mode_fb_cmd2 mode_cmd = { }; 205 - struct fb_info *info; 205 + struct fb_info *info = fb_helper->info; 206 206 struct drm_gem_object *gobj; 207 207 struct radeon_bo *rbo; 208 208 struct drm_framebuffer *fb; ··· 243 243 fb_helper->funcs = &radeon_fbdev_fb_helper_funcs; 244 244 fb_helper->fb = fb; 245 245 246 - /* okay we have an object now allocate the framebuffer */ 247 - info = drm_fb_helper_alloc_info(fb_helper); 248 - if (IS_ERR(info)) { 249 - ret = PTR_ERR(info); 250 - goto err_drm_framebuffer_unregister_private; 251 - } 252 - 253 246 info->fbops = &radeon_fbdev_fb_ops; 254 247 255 248 /* radeon resume is fragile and needs a vt switch to help it along */ ··· 268 275 269 276 return 0; 270 277 271 - err_drm_framebuffer_unregister_private: 272 - fb_helper->fb = NULL; 273 - drm_framebuffer_unregister_private(fb); 274 - drm_framebuffer_cleanup(fb); 275 278 err_kfree: 276 279 kfree(fb); 277 280 err_radeon_fbdev_destroy_pinned_object:
+1 -8
drivers/gpu/drm/tegra/fbdev.c
··· 73 73 struct tegra_drm *tegra = helper->dev->dev_private; 74 74 struct drm_device *drm = helper->dev; 75 75 struct drm_mode_fb_cmd2 cmd = { 0 }; 76 + struct fb_info *info = helper->info; 76 77 unsigned int bytes_per_pixel; 77 78 struct drm_framebuffer *fb; 78 79 unsigned long offset; 79 - struct fb_info *info; 80 80 struct tegra_bo *bo; 81 81 size_t size; 82 82 int err; ··· 96 96 bo = tegra_bo_create(drm, size, 0); 97 97 if (IS_ERR(bo)) 98 98 return PTR_ERR(bo); 99 - 100 - info = drm_fb_helper_alloc_info(helper); 101 - if (IS_ERR(info)) { 102 - dev_err(drm->dev, "failed to allocate framebuffer info\n"); 103 - drm_gem_object_put(&bo->gem); 104 - return PTR_ERR(info); 105 - } 106 99 107 100 fb = tegra_fb_alloc(drm, 108 101 drm_get_format_info(drm, cmd.pixel_format, cmd.modifier[0]),
-12
include/drm/drm_fb_helper.h
··· 257 257 int drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper, 258 258 bool force); 259 259 260 - struct fb_info *drm_fb_helper_alloc_info(struct drm_fb_helper *fb_helper); 261 - void drm_fb_helper_release_info(struct drm_fb_helper *fb_helper); 262 260 void drm_fb_helper_unregister_info(struct drm_fb_helper *fb_helper); 263 261 void drm_fb_helper_fill_info(struct fb_info *info, 264 262 struct drm_fb_helper *fb_helper, ··· 336 338 drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper) 337 339 { 338 340 return 0; 339 - } 340 - 341 - static inline struct fb_info * 342 - drm_fb_helper_alloc_info(struct drm_fb_helper *fb_helper) 343 - { 344 - return NULL; 345 - } 346 - 347 - static inline void drm_fb_helper_release_info(struct drm_fb_helper *fb_helper) 348 - { 349 341 } 350 342 351 343 static inline void drm_fb_helper_unregister_info(struct drm_fb_helper *fb_helper)