aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/console/fbcon.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/console/fbcon.c')
-rw-r--r--drivers/video/console/fbcon.c114
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
284static 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
284static void fb_flashcursor(void *private) 296static 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
1022static void fbcon_deinit(struct vc_data *vc) 1035static 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)