diff options
Diffstat (limited to 'drivers/video/console/fbcon.c')
-rw-r--r-- | drivers/video/console/fbcon.c | 114 |
1 files changed, 36 insertions, 78 deletions
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index 0fc8bb499c3f..3cf1b61ff1f8 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c | |||
@@ -281,6 +281,18 @@ static inline int get_color(struct vc_data *vc, struct fb_info *info, | |||
281 | return color; | 281 | return color; |
282 | } | 282 | } |
283 | 283 | ||
284 | static void fbcon_update_softback(struct vc_data *vc) | ||
285 | { | ||
286 | int l = fbcon_softback_size / vc->vc_size_row; | ||
287 | |||
288 | if (l > 5) | ||
289 | softback_end = softback_buf + l * vc->vc_size_row; | ||
290 | else | ||
291 | /* Smaller scrollback makes no sense, and 0 would screw | ||
292 | the operation totally */ | ||
293 | softback_top = 0; | ||
294 | } | ||
295 | |||
284 | static void fb_flashcursor(void *private) | 296 | static void fb_flashcursor(void *private) |
285 | { | 297 | { |
286 | struct fb_info *info = private; | 298 | struct fb_info *info = private; |
@@ -618,6 +630,15 @@ static int con2fb_release_oldinfo(struct vc_data *vc, struct fb_info *oldinfo, | |||
618 | kfree(oldinfo->fbcon_par); | 630 | kfree(oldinfo->fbcon_par); |
619 | oldinfo->fbcon_par = NULL; | 631 | oldinfo->fbcon_par = NULL; |
620 | module_put(oldinfo->fbops->owner); | 632 | module_put(oldinfo->fbops->owner); |
633 | /* | ||
634 | If oldinfo and newinfo are driving the same hardware, | ||
635 | the fb_release() method of oldinfo may attempt to | ||
636 | restore the hardware state. This will leave the | ||
637 | newinfo in an undefined state. Thus, a call to | ||
638 | fb_set_par() may be needed for the newinfo. | ||
639 | */ | ||
640 | if (newinfo->fbops->fb_set_par) | ||
641 | newinfo->fbops->fb_set_par(newinfo); | ||
621 | } | 642 | } |
622 | 643 | ||
623 | return err; | 644 | return err; |
@@ -1007,16 +1028,8 @@ static void fbcon_init(struct vc_data *vc, int init) | |||
1007 | if (logo) | 1028 | if (logo) |
1008 | fbcon_prepare_logo(vc, info, cols, rows, new_cols, new_rows); | 1029 | fbcon_prepare_logo(vc, info, cols, rows, new_cols, new_rows); |
1009 | 1030 | ||
1010 | if (vc == svc && softback_buf) { | 1031 | if (vc == svc && softback_buf) |
1011 | int l = fbcon_softback_size / vc->vc_size_row; | 1032 | fbcon_update_softback(vc); |
1012 | if (l > 5) | ||
1013 | softback_end = softback_buf + l * vc->vc_size_row; | ||
1014 | else { | ||
1015 | /* Smaller scrollback makes no sense, and 0 would screw | ||
1016 | the operation totally */ | ||
1017 | softback_top = 0; | ||
1018 | } | ||
1019 | } | ||
1020 | } | 1033 | } |
1021 | 1034 | ||
1022 | static void fbcon_deinit(struct vc_data *vc) | 1035 | static void fbcon_deinit(struct vc_data *vc) |
@@ -1223,18 +1236,8 @@ static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var, | |||
1223 | vc_resize(vc, cols, rows); | 1236 | vc_resize(vc, cols, rows); |
1224 | if (CON_IS_VISIBLE(vc)) { | 1237 | if (CON_IS_VISIBLE(vc)) { |
1225 | update_screen(vc); | 1238 | update_screen(vc); |
1226 | if (softback_buf) { | 1239 | if (softback_buf) |
1227 | int l = fbcon_softback_size / vc->vc_size_row; | 1240 | fbcon_update_softback(vc); |
1228 | |||
1229 | if (l > 5) | ||
1230 | softback_end = softback_buf + l * | ||
1231 | vc->vc_size_row; | ||
1232 | else { | ||
1233 | /* Smaller scrollback makes no sense, and 0 | ||
1234 | would screw the operation totally */ | ||
1235 | softback_top = 0; | ||
1236 | } | ||
1237 | } | ||
1238 | } | 1241 | } |
1239 | } | 1242 | } |
1240 | 1243 | ||
@@ -1892,24 +1895,11 @@ static int fbcon_resize(struct vc_data *vc, unsigned int width, | |||
1892 | mode = fb_find_best_mode(&var, &info->modelist); | 1895 | mode = fb_find_best_mode(&var, &info->modelist); |
1893 | if (mode == NULL) | 1896 | if (mode == NULL) |
1894 | return -EINVAL; | 1897 | return -EINVAL; |
1898 | display_to_var(&var, p); | ||
1895 | fb_videomode_to_var(&var, mode); | 1899 | fb_videomode_to_var(&var, mode); |
1900 | |||
1896 | if (width > var.xres/fw || height > var.yres/fh) | 1901 | if (width > var.xres/fw || height > var.yres/fh) |
1897 | return -EINVAL; | 1902 | return -EINVAL; |
1898 | /* | ||
1899 | * The following can probably have any value... Do we need to | ||
1900 | * set all of them? | ||
1901 | */ | ||
1902 | var.bits_per_pixel = p->bits_per_pixel; | ||
1903 | var.xres_virtual = p->xres_virtual; | ||
1904 | var.yres_virtual = p->yres_virtual; | ||
1905 | var.accel_flags = p->accel_flags; | ||
1906 | var.width = p->width; | ||
1907 | var.height = p->height; | ||
1908 | var.red = p->red; | ||
1909 | var.green = p->green; | ||
1910 | var.blue = p->blue; | ||
1911 | var.transp = p->transp; | ||
1912 | var.nonstd = p->nonstd; | ||
1913 | 1903 | ||
1914 | DPRINTK("resize now %ix%i\n", var.xres, var.yres); | 1904 | DPRINTK("resize now %ix%i\n", var.xres, var.yres); |
1915 | if (CON_IS_VISIBLE(vc)) { | 1905 | if (CON_IS_VISIBLE(vc)) { |
@@ -1933,19 +1923,11 @@ static int fbcon_switch(struct vc_data *vc) | |||
1933 | info = registered_fb[con2fb_map[vc->vc_num]]; | 1923 | info = registered_fb[con2fb_map[vc->vc_num]]; |
1934 | 1924 | ||
1935 | if (softback_top) { | 1925 | if (softback_top) { |
1936 | int l = fbcon_softback_size / vc->vc_size_row; | ||
1937 | if (softback_lines) | 1926 | if (softback_lines) |
1938 | fbcon_set_origin(vc); | 1927 | fbcon_set_origin(vc); |
1939 | softback_top = softback_curr = softback_in = softback_buf; | 1928 | softback_top = softback_curr = softback_in = softback_buf; |
1940 | softback_lines = 0; | 1929 | softback_lines = 0; |
1941 | 1930 | fbcon_update_softback(vc); | |
1942 | if (l > 5) | ||
1943 | softback_end = softback_buf + l * vc->vc_size_row; | ||
1944 | else { | ||
1945 | /* Smaller scrollback makes no sense, and 0 would screw | ||
1946 | the operation totally */ | ||
1947 | softback_top = 0; | ||
1948 | } | ||
1949 | } | 1931 | } |
1950 | 1932 | ||
1951 | if (logo_shown >= 0) { | 1933 | if (logo_shown >= 0) { |
@@ -2235,17 +2217,8 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h, | |||
2235 | /* reset wrap/pan */ | 2217 | /* reset wrap/pan */ |
2236 | info->var.xoffset = info->var.yoffset = p->yscroll = 0; | 2218 | info->var.xoffset = info->var.yoffset = p->yscroll = 0; |
2237 | vc_resize(vc, info->var.xres / w, info->var.yres / h); | 2219 | vc_resize(vc, info->var.xres / w, info->var.yres / h); |
2238 | if (CON_IS_VISIBLE(vc) && softback_buf) { | 2220 | if (CON_IS_VISIBLE(vc) && softback_buf) |
2239 | int l = fbcon_softback_size / vc->vc_size_row; | 2221 | fbcon_update_softback(vc); |
2240 | if (l > 5) | ||
2241 | softback_end = | ||
2242 | softback_buf + l * vc->vc_size_row; | ||
2243 | else { | ||
2244 | /* Smaller scrollback makes no sense, and 0 would screw | ||
2245 | the operation totally */ | ||
2246 | softback_top = 0; | ||
2247 | } | ||
2248 | } | ||
2249 | } else if (CON_IS_VISIBLE(vc) | 2222 | } else if (CON_IS_VISIBLE(vc) |
2250 | && vc->vc_mode == KD_TEXT) { | 2223 | && vc->vc_mode == KD_TEXT) { |
2251 | fbcon_clear_margins(vc, 0); | 2224 | fbcon_clear_margins(vc, 0); |
@@ -2615,16 +2588,8 @@ static void fbcon_modechanged(struct fb_info *info) | |||
2615 | update_var(vc->vc_num, info); | 2588 | update_var(vc->vc_num, info); |
2616 | fbcon_set_palette(vc, color_table); | 2589 | fbcon_set_palette(vc, color_table); |
2617 | update_screen(vc); | 2590 | update_screen(vc); |
2618 | if (softback_buf) { | 2591 | if (softback_buf) |
2619 | int l = fbcon_softback_size / vc->vc_size_row; | 2592 | fbcon_update_softback(vc); |
2620 | if (l > 5) | ||
2621 | softback_end = softback_buf + l * vc->vc_size_row; | ||
2622 | else { | ||
2623 | /* Smaller scrollback makes no sense, and 0 | ||
2624 | would screw the operation totally */ | ||
2625 | softback_top = 0; | ||
2626 | } | ||
2627 | } | ||
2628 | } | 2593 | } |
2629 | } | 2594 | } |
2630 | 2595 | ||
@@ -2659,16 +2624,8 @@ static void fbcon_set_all_vcs(struct fb_info *info) | |||
2659 | update_var(vc->vc_num, info); | 2624 | update_var(vc->vc_num, info); |
2660 | fbcon_set_palette(vc, color_table); | 2625 | fbcon_set_palette(vc, color_table); |
2661 | update_screen(vc); | 2626 | update_screen(vc); |
2662 | if (softback_buf) { | 2627 | if (softback_buf) |
2663 | int l = fbcon_softback_size / vc->vc_size_row; | 2628 | fbcon_update_softback(vc); |
2664 | if (l > 5) | ||
2665 | softback_end = softback_buf + l * vc->vc_size_row; | ||
2666 | else { | ||
2667 | /* Smaller scrollback makes no sense, and 0 | ||
2668 | would screw the operation totally */ | ||
2669 | softback_top = 0; | ||
2670 | } | ||
2671 | } | ||
2672 | } | 2629 | } |
2673 | } | 2630 | } |
2674 | } | 2631 | } |
@@ -2758,7 +2715,8 @@ static void fbcon_new_modelist(struct fb_info *info) | |||
2758 | continue; | 2715 | continue; |
2759 | vc = vc_cons[i].d; | 2716 | vc = vc_cons[i].d; |
2760 | display_to_var(&var, &fb_display[i]); | 2717 | display_to_var(&var, &fb_display[i]); |
2761 | mode = fb_find_nearest_mode(&var, &info->modelist); | 2718 | mode = fb_find_nearest_mode(fb_display[i].mode, |
2719 | &info->modelist); | ||
2762 | fb_videomode_to_var(&var, mode); | 2720 | fb_videomode_to_var(&var, mode); |
2763 | 2721 | ||
2764 | if (vc) | 2722 | if (vc) |