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