]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
staging: fbtft: cleanup error handling in fbtft_framebuffer_alloc()
authorAbdun Nihaal <abdun.nihaal@gmail.com>
Tue, 1 Jul 2025 16:45:36 +0000 (22:15 +0530)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 9 Jul 2025 11:11:07 +0000 (13:11 +0200)
The error handling in fbtft_framebuffer_alloc() mixes managed allocation
and plain allocation, and performs error handling in an order different
from the order in fbtft_framebuffer_release().

Fix them by moving vmem allocation closer to where it is used, and using
plain kzalloc() for txbuf allocation. Also remove the duplicate call to
fb_deferred_io_cleanup().

Suggested-by: Andy Shevchenko <andriy.shevchenko@intel.com>
Suggested-by: Dan Carpenter <dan.carpenter@linaro.org>
Signed-off-by: Abdun Nihaal <abdun.nihaal@gmail.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Reviewed-by: Dan Carpenter <dan.carpenter@linaro.org>
Link: https://lore.kernel.org/r/20250701164537.243282-1-abdun.nihaal@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/staging/fbtft/fbtft-core.c

index d920164e7710b1927f7b3da2064bbde11467bd18..9e7b84071174cff31d04557a65285061152c3c40 100644 (file)
@@ -568,18 +568,13 @@ struct fb_info *fbtft_framebuffer_alloc(struct fbtft_display *display,
                height = display->height;
        }
 
-       vmem_size = display->width * display->height * bpp / 8;
-       vmem = vzalloc(vmem_size);
-       if (!vmem)
-               goto alloc_fail;
-
        fbdefio = devm_kzalloc(dev, sizeof(struct fb_deferred_io), GFP_KERNEL);
        if (!fbdefio)
-               goto alloc_fail;
+               return NULL;
 
        buf = devm_kzalloc(dev, 128, GFP_KERNEL);
        if (!buf)
-               goto alloc_fail;
+               return NULL;
 
        if (display->gamma_num && display->gamma_len) {
                gamma_curves = devm_kcalloc(dev,
@@ -588,12 +583,17 @@ struct fb_info *fbtft_framebuffer_alloc(struct fbtft_display *display,
                                            sizeof(gamma_curves[0]),
                                            GFP_KERNEL);
                if (!gamma_curves)
-                       goto alloc_fail;
+                       return NULL;
        }
 
        info = framebuffer_alloc(sizeof(struct fbtft_par), dev);
        if (!info)
-               goto alloc_fail;
+               return NULL;
+
+       vmem_size = display->width * display->height * bpp / 8;
+       vmem = vzalloc(vmem_size);
+       if (!vmem)
+               goto release_framebuf;
 
        info->screen_buffer = vmem;
        info->fbops = &fbtft_ops;
@@ -613,7 +613,7 @@ struct fb_info *fbtft_framebuffer_alloc(struct fbtft_display *display,
        info->fix.accel =          FB_ACCEL_NONE;
        info->fix.smem_len =       vmem_size;
        if (fb_deferred_io_init(info))
-               goto release_framebuf;
+               goto release_screen_buffer;
 
        info->var.rotate =         pdata->rotate;
        info->var.xres =           width;
@@ -668,7 +668,7 @@ struct fb_info *fbtft_framebuffer_alloc(struct fbtft_display *display,
 #endif
 
        if (txbuflen > 0) {
-               txbuf = devm_kzalloc(par->info->device, txbuflen, GFP_KERNEL);
+               txbuf = kzalloc(txbuflen, GFP_KERNEL);
                if (!txbuf)
                        goto cleanup_deferred;
                par->txbuf.buf = txbuf;
@@ -694,13 +694,10 @@ struct fb_info *fbtft_framebuffer_alloc(struct fbtft_display *display,
 
 cleanup_deferred:
        fb_deferred_io_cleanup(info);
+release_screen_buffer:
+       vfree(info->screen_buffer);
 release_framebuf:
-       fb_deferred_io_cleanup(info);
        framebuffer_release(info);
-
-alloc_fail:
-       vfree(vmem);
-
        return NULL;
 }
 EXPORT_SYMBOL(fbtft_framebuffer_alloc);
@@ -713,6 +710,9 @@ EXPORT_SYMBOL(fbtft_framebuffer_alloc);
  */
 void fbtft_framebuffer_release(struct fb_info *info)
 {
+       struct fbtft_par *par = info->par;
+
+       kfree(par->txbuf.buf);
        fb_deferred_io_cleanup(info);
        vfree(info->screen_buffer);
        framebuffer_release(info);