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), |
