// SPDX-License-Identifier: GPL-2.0-or-later #include <linux/export.h> #include <linux/fb.h> #include <linux/mutex.h> #include <linux/slab.h> /** * framebuffer_alloc - creates a new frame buffer info structure * * @size: size of driver private data, can be zero * @dev: pointer to the device for this fb, this can be NULL * * Creates a new frame buffer info structure. Also reserves @size bytes * for driver private data (info->par). info->par (if any) will be * aligned to sizeof(long). The new instances of struct fb_info and * the driver private data are both cleared to zero. * * Returns the new structure, or NULL if an error occurred. * */ struct fb_info *framebuffer_alloc(size_t size, struct device *dev) { #define BYTES_PER_LONG (BITS_PER_LONG/8) #define PADDING (BYTES_PER_LONG - (sizeof(struct fb_info) % BYTES_PER_LONG)) int fb_info_size = sizeof(struct fb_info); struct fb_info *info; char *p; if (size) fb_info_size += PADDING; p = kzalloc(fb_info_size + size, GFP_KERNEL); if (!p) return NULL; info = (struct fb_info *) p; if (size) info->par = p + fb_info_size; info->device = dev; info->fbcon_rotate_hint = -1; #if IS_ENABLED(CONFIG_FB_BACKLIGHT) mutex_init(&info->bl_curve_mutex); #endif return info; #undef PADDING #undef BYTES_PER_LONG } EXPORT_SYMBOL(framebuffer_alloc); /** * framebuffer_release - marks the structure available for freeing * * @info: frame buffer info structure * * Drop the reference count of the device embedded in the * framebuffer info structure. * */ void framebuffer_release(struct fb_info *info) { if (!info) return; if (WARN_ON(refcount_read(&info->count))) return; #if IS_ENABLED(CONFIG_FB_BACKLIGHT) mutex_destroy(&info->bl_curve_mutex); #endif kfree(info); } EXPORT_SYMBOL