80 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			80 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| // 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(framebuffer_release);
 |