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(size: 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(lock: &info->bl_curve_mutex); |
75 | #endif |
76 | |
77 | kfree(objp: info); |
78 | } |
79 | EXPORT_SYMBOL(framebuffer_release); |
80 |