xref: /linux/drivers/video/fbdev/core/fb_info.c (revision a940daa52167e9db8ecce82213813b735a9d9f23)
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 Zimmermann struct 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 Zimmermann void 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