diff options
Diffstat (limited to 'drivers/video/fbmem.c')
-rw-r--r-- | drivers/video/fbmem.c | 69 |
1 files changed, 37 insertions, 32 deletions
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index 4ff853fbe0be..70be7009f8af 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c | |||
@@ -62,16 +62,26 @@ int num_registered_fb; | |||
62 | * Helpers | 62 | * Helpers |
63 | */ | 63 | */ |
64 | 64 | ||
65 | int fb_get_color_depth(struct fb_var_screeninfo *var) | 65 | int fb_get_color_depth(struct fb_var_screeninfo *var, |
66 | struct fb_fix_screeninfo *fix) | ||
66 | { | 67 | { |
67 | if (var->green.length == var->blue.length && | 68 | int depth = 0; |
68 | var->green.length == var->red.length && | 69 | |
69 | !var->green.offset && !var->blue.offset && | 70 | if (fix->visual == FB_VISUAL_MONO01 || |
70 | !var->red.offset) | 71 | fix->visual == FB_VISUAL_MONO10) |
71 | return var->green.length; | 72 | depth = 1; |
72 | else | 73 | else { |
73 | return (var->green.length + var->red.length + | 74 | if (var->green.length == var->blue.length && |
74 | var->blue.length); | 75 | var->green.length == var->red.length && |
76 | var->green.offset == var->blue.offset && | ||
77 | var->green.offset == var->red.offset) | ||
78 | depth = var->green.length; | ||
79 | else | ||
80 | depth = var->green.length + var->red.length + | ||
81 | var->blue.length; | ||
82 | } | ||
83 | |||
84 | return depth; | ||
75 | } | 85 | } |
76 | EXPORT_SYMBOL(fb_get_color_depth); | 86 | EXPORT_SYMBOL(fb_get_color_depth); |
77 | 87 | ||
@@ -80,15 +90,7 @@ EXPORT_SYMBOL(fb_get_color_depth); | |||
80 | */ | 90 | */ |
81 | void fb_pad_aligned_buffer(u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch, u32 height) | 91 | void fb_pad_aligned_buffer(u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch, u32 height) |
82 | { | 92 | { |
83 | int i, j; | 93 | __fb_pad_aligned_buffer(dst, d_pitch, src, s_pitch, height); |
84 | |||
85 | for (i = height; i--; ) { | ||
86 | /* s_pitch is a few bytes at the most, memcpy is suboptimal */ | ||
87 | for (j = 0; j < s_pitch; j++) | ||
88 | dst[j] = src[j]; | ||
89 | src += s_pitch; | ||
90 | dst += d_pitch; | ||
91 | } | ||
92 | } | 94 | } |
93 | EXPORT_SYMBOL(fb_pad_aligned_buffer); | 95 | EXPORT_SYMBOL(fb_pad_aligned_buffer); |
94 | 96 | ||
@@ -249,13 +251,18 @@ static void fb_set_logo(struct fb_info *info, | |||
249 | const struct linux_logo *logo, u8 *dst, | 251 | const struct linux_logo *logo, u8 *dst, |
250 | int depth) | 252 | int depth) |
251 | { | 253 | { |
252 | int i, j, k, fg = 1; | 254 | int i, j, k; |
253 | const u8 *src = logo->data; | 255 | const u8 *src = logo->data; |
254 | u8 d, xor = (info->fix.visual == FB_VISUAL_MONO01) ? 0xff : 0; | 256 | u8 xor = (info->fix.visual == FB_VISUAL_MONO01) ? 0xff : 0; |
257 | u8 fg = 1, d; | ||
255 | 258 | ||
256 | if (fb_get_color_depth(&info->var) == 3) | 259 | if (fb_get_color_depth(&info->var, &info->fix) == 3) |
257 | fg = 7; | 260 | fg = 7; |
258 | 261 | ||
262 | if (info->fix.visual == FB_VISUAL_MONO01 || | ||
263 | info->fix.visual == FB_VISUAL_MONO10) | ||
264 | fg = ~((u8) (0xfff << info->var.green.length)); | ||
265 | |||
259 | switch (depth) { | 266 | switch (depth) { |
260 | case 4: | 267 | case 4: |
261 | for (i = 0; i < logo->height; i++) | 268 | for (i = 0; i < logo->height; i++) |
@@ -318,7 +325,7 @@ static struct logo_data { | |||
318 | 325 | ||
319 | int fb_prepare_logo(struct fb_info *info) | 326 | int fb_prepare_logo(struct fb_info *info) |
320 | { | 327 | { |
321 | int depth = fb_get_color_depth(&info->var); | 328 | int depth = fb_get_color_depth(&info->var, &info->fix); |
322 | 329 | ||
323 | memset(&fb_logo, 0, sizeof(struct logo_data)); | 330 | memset(&fb_logo, 0, sizeof(struct logo_data)); |
324 | 331 | ||
@@ -684,11 +691,13 @@ fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var) | |||
684 | 691 | ||
685 | if (!err && (flags & FBINFO_MISC_USEREVENT)) { | 692 | if (!err && (flags & FBINFO_MISC_USEREVENT)) { |
686 | struct fb_event event; | 693 | struct fb_event event; |
694 | int evnt = (var->activate & FB_ACTIVATE_ALL) ? | ||
695 | FB_EVENT_MODE_CHANGE_ALL : | ||
696 | FB_EVENT_MODE_CHANGE; | ||
687 | 697 | ||
688 | info->flags &= ~FBINFO_MISC_USEREVENT; | 698 | info->flags &= ~FBINFO_MISC_USEREVENT; |
689 | event.info = info; | 699 | event.info = info; |
690 | notifier_call_chain(&fb_notifier_list, | 700 | notifier_call_chain(&fb_notifier_list, evnt, |
691 | FB_EVENT_MODE_CHANGE, | ||
692 | &event); | 701 | &event); |
693 | } | 702 | } |
694 | } | 703 | } |
@@ -1012,6 +1021,7 @@ register_framebuffer(struct fb_info *fb_info) | |||
1012 | { | 1021 | { |
1013 | int i; | 1022 | int i; |
1014 | struct fb_event event; | 1023 | struct fb_event event; |
1024 | struct fb_videomode mode; | ||
1015 | 1025 | ||
1016 | if (num_registered_fb == FB_MAX) | 1026 | if (num_registered_fb == FB_MAX) |
1017 | return -ENXIO; | 1027 | return -ENXIO; |
@@ -1042,16 +1052,11 @@ register_framebuffer(struct fb_info *fb_info) | |||
1042 | } | 1052 | } |
1043 | fb_info->pixmap.offset = 0; | 1053 | fb_info->pixmap.offset = 0; |
1044 | 1054 | ||
1045 | if (!fb_info->modelist.prev || | 1055 | if (!fb_info->modelist.prev || !fb_info->modelist.next) |
1046 | !fb_info->modelist.next || | ||
1047 | list_empty(&fb_info->modelist)) { | ||
1048 | struct fb_videomode mode; | ||
1049 | |||
1050 | INIT_LIST_HEAD(&fb_info->modelist); | 1056 | INIT_LIST_HEAD(&fb_info->modelist); |
1051 | fb_var_to_videomode(&mode, &fb_info->var); | ||
1052 | fb_add_videomode(&mode, &fb_info->modelist); | ||
1053 | } | ||
1054 | 1057 | ||
1058 | fb_var_to_videomode(&mode, &fb_info->var); | ||
1059 | fb_add_videomode(&mode, &fb_info->modelist); | ||
1055 | registered_fb[i] = fb_info; | 1060 | registered_fb[i] = fb_info; |
1056 | 1061 | ||
1057 | devfs_mk_cdev(MKDEV(FB_MAJOR, i), | 1062 | devfs_mk_cdev(MKDEV(FB_MAJOR, i), |