1f0f6839bSThomas Zimmermann // SPDX-License-Identifier: GPL-2.0-or-later 2f0f6839bSThomas Zimmermann 3f0f6839bSThomas Zimmermann #include <linux/export.h> 4f0f6839bSThomas Zimmermann #include <linux/fb.h> 5f0f6839bSThomas Zimmermann #include <linux/mutex.h> 6f0f6839bSThomas Zimmermann #include <linux/slab.h> 7f0f6839bSThomas Zimmermann 8f0f6839bSThomas Zimmermann /** 9f0f6839bSThomas Zimmermann * framebuffer_alloc - creates a new frame buffer info structure 10f0f6839bSThomas Zimmermann * 11f0f6839bSThomas Zimmermann * @size: size of driver private data, can be zero 12f0f6839bSThomas Zimmermann * @dev: pointer to the device for this fb, this can be NULL 13f0f6839bSThomas Zimmermann * 14f0f6839bSThomas Zimmermann * Creates a new frame buffer info structure. Also reserves @size bytes 15f0f6839bSThomas Zimmermann * for driver private data (info->par). info->par (if any) will be 16*c07e1f20SThomas Zimmermann * aligned to sizeof(long). The new instances of struct fb_info and 17*c07e1f20SThomas Zimmermann * the driver private data are both cleared to zero. 18f0f6839bSThomas Zimmermann * 19f0f6839bSThomas Zimmermann * Returns the new structure, or NULL if an error occurred. 20f0f6839bSThomas Zimmermann * 21f0f6839bSThomas Zimmermann */ framebuffer_alloc(size_t size,struct device * dev)22f0f6839bSThomas Zimmermannstruct fb_info *framebuffer_alloc(size_t size, struct device *dev) 23f0f6839bSThomas Zimmermann { 24f0f6839bSThomas Zimmermann #define BYTES_PER_LONG (BITS_PER_LONG/8) 25f0f6839bSThomas Zimmermann #define PADDING (BYTES_PER_LONG - (sizeof(struct fb_info) % BYTES_PER_LONG)) 26f0f6839bSThomas Zimmermann int fb_info_size = sizeof(struct fb_info); 27f0f6839bSThomas Zimmermann struct fb_info *info; 28f0f6839bSThomas Zimmermann char *p; 29f0f6839bSThomas Zimmermann 30f0f6839bSThomas Zimmermann if (size) 31f0f6839bSThomas Zimmermann fb_info_size += PADDING; 32f0f6839bSThomas Zimmermann 33f0f6839bSThomas Zimmermann p = kzalloc(fb_info_size + size, GFP_KERNEL); 34f0f6839bSThomas Zimmermann 35f0f6839bSThomas Zimmermann if (!p) 36f0f6839bSThomas Zimmermann return NULL; 37f0f6839bSThomas Zimmermann 38f0f6839bSThomas Zimmermann info = (struct fb_info *) p; 39f0f6839bSThomas Zimmermann 40f0f6839bSThomas Zimmermann if (size) 41f0f6839bSThomas Zimmermann info->par = p + fb_info_size; 42f0f6839bSThomas Zimmermann 43f0f6839bSThomas Zimmermann info->device = dev; 44f0f6839bSThomas Zimmermann info->fbcon_rotate_hint = -1; 45f0f6839bSThomas Zimmermann 46f0f6839bSThomas Zimmermann #if IS_ENABLED(CONFIG_FB_BACKLIGHT) 47f0f6839bSThomas Zimmermann mutex_init(&info->bl_curve_mutex); 48f0f6839bSThomas Zimmermann #endif 49f0f6839bSThomas Zimmermann 50f0f6839bSThomas Zimmermann return info; 51f0f6839bSThomas Zimmermann #undef PADDING 52f0f6839bSThomas Zimmermann #undef BYTES_PER_LONG 53f0f6839bSThomas Zimmermann } 54f0f6839bSThomas Zimmermann EXPORT_SYMBOL(framebuffer_alloc); 55f0f6839bSThomas Zimmermann 56f0f6839bSThomas Zimmermann /** 57f0f6839bSThomas Zimmermann * framebuffer_release - marks the structure available for freeing 58f0f6839bSThomas Zimmermann * 59f0f6839bSThomas Zimmermann * @info: frame buffer info structure 60f0f6839bSThomas Zimmermann * 61f0f6839bSThomas Zimmermann * Drop the reference count of the device embedded in the 62f0f6839bSThomas Zimmermann * framebuffer info structure. 63f0f6839bSThomas Zimmermann * 64f0f6839bSThomas Zimmermann */ framebuffer_release(struct fb_info * info)65f0f6839bSThomas Zimmermannvoid framebuffer_release(struct fb_info *info) 66f0f6839bSThomas Zimmermann { 67f0f6839bSThomas Zimmermann if (!info) 68f0f6839bSThomas Zimmermann return; 69f0f6839bSThomas Zimmermann 70f0f6839bSThomas Zimmermann if (WARN_ON(refcount_read(&info->count))) 71f0f6839bSThomas Zimmermann return; 72f0f6839bSThomas Zimmermann 73f0f6839bSThomas Zimmermann #if IS_ENABLED(CONFIG_FB_BACKLIGHT) 74f0f6839bSThomas Zimmermann mutex_destroy(&info->bl_curve_mutex); 75f0f6839bSThomas Zimmermann #endif 76f0f6839bSThomas Zimmermann 77f0f6839bSThomas Zimmermann kfree(info); 78f0f6839bSThomas Zimmermann } 79f0f6839bSThomas Zimmermann EXPORT_SYMBOL(framebuffer_release); 80