aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAntonino A. Daplas <adaplas@gmail.com>2007-07-17 07:05:32 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-17 13:23:11 -0400
commitd1baa4ffa677bf6986c460fcfd4cdaf8bfe66f0e (patch)
treebb1670cd6842187babf0b6e2792f9c736646dbbc /drivers
parent2f7bb99fc9eb7a3d3840dc0a507049b7be1daba8 (diff)
fbcon: set_con2fb_map fixes
set_con2fb_map() has regressed for some time. Using fbcon=map:01, for example, works only if there is only 1 working framebuffer. Trying to do a set_con2fb_map() on a non-allocated vc will freeze the system. - ensure that succeeding drivers after the first gets mapped to the console - remove fbcon_preset_display() and modify fbcon_set_display() to include the former's functionality - ensure that binding and unbinding succeeds if multiple drivers are mapped to the console Signed-off-by: Antonino Daplas <adaplas@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/video/console/fbcon.c64
1 files changed, 25 insertions, 39 deletions
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index 7ba21eb1676c..13b67ee8b3c0 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -192,9 +192,7 @@ static __inline__ void ypan_down(struct vc_data *vc, int count);
192static void fbcon_bmove_rec(struct vc_data *vc, struct display *p, int sy, int sx, 192static void fbcon_bmove_rec(struct vc_data *vc, struct display *p, int sy, int sx,
193 int dy, int dx, int height, int width, u_int y_break); 193 int dy, int dx, int height, int width, u_int y_break);
194static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var, 194static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var,
195 struct vc_data *vc); 195 int unit);
196static void fbcon_preset_disp(struct fb_info *info, struct fb_var_screeninfo *var,
197 int unit);
198static void fbcon_redraw_move(struct vc_data *vc, struct display *p, 196static void fbcon_redraw_move(struct vc_data *vc, struct display *p,
199 int line, int count, int dy); 197 int line, int count, int dy);
200static void fbcon_modechanged(struct fb_info *info); 198static void fbcon_modechanged(struct fb_info *info);
@@ -745,7 +743,9 @@ static int con2fb_acquire_newinfo(struct vc_data *vc, struct fb_info *info,
745 743
746 if (!err) { 744 if (!err) {
747 info->fbcon_par = ops; 745 info->fbcon_par = ops;
748 set_blitting_type(vc, info); 746
747 if (vc)
748 set_blitting_type(vc, info);
749 } 749 }
750 750
751 if (err) { 751 if (err) {
@@ -807,11 +807,7 @@ static void con2fb_init_display(struct vc_data *vc, struct fb_info *info,
807 807
808 ops->flags |= FBCON_FLAGS_INIT; 808 ops->flags |= FBCON_FLAGS_INIT;
809 ops->graphics = 0; 809 ops->graphics = 0;
810 810 fbcon_set_disp(info, &info->var, unit);
811 if (vc)
812 fbcon_set_disp(info, &info->var, vc);
813 else
814 fbcon_preset_disp(info, &info->var, unit);
815 811
816 if (show_logo) { 812 if (show_logo) {
817 struct vc_data *fg_vc = vc_cons[fg_console].d; 813 struct vc_data *fg_vc = vc_cons[fg_console].d;
@@ -1116,6 +1112,9 @@ static void fbcon_init(struct vc_data *vc, int init)
1116 if (var_to_display(p, &info->var, info)) 1112 if (var_to_display(p, &info->var, info))
1117 return; 1113 return;
1118 1114
1115 if (!info->fbcon_par)
1116 con2fb_acquire_newinfo(vc, info, vc->vc_num, -1);
1117
1119 /* If we are not the first console on this 1118 /* If we are not the first console on this
1120 fb, copy the font from that console */ 1119 fb, copy the font from that console */
1121 t = &fb_display[fg_console]; 1120 t = &fb_display[fg_console];
@@ -1382,36 +1381,29 @@ static int scrollback_phys_max = 0;
1382static int scrollback_max = 0; 1381static int scrollback_max = 0;
1383static int scrollback_current = 0; 1382static int scrollback_current = 0;
1384 1383
1385/*
1386 * If no vc is existent yet, just set struct display
1387 */
1388static void fbcon_preset_disp(struct fb_info *info, struct fb_var_screeninfo *var,
1389 int unit)
1390{
1391 struct display *p = &fb_display[unit];
1392 struct display *t = &fb_display[fg_console];
1393
1394 if (var_to_display(p, var, info))
1395 return;
1396
1397 p->fontdata = t->fontdata;
1398 p->userfont = t->userfont;
1399 if (p->userfont)
1400 REFCOUNT(p->fontdata)++;
1401}
1402
1403static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var, 1384static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var,
1404 struct vc_data *vc) 1385 int unit)
1405{ 1386{
1406 struct display *p = &fb_display[vc->vc_num], *t; 1387 struct display *p, *t;
1407 struct vc_data **default_mode = vc->vc_display_fg; 1388 struct vc_data **default_mode, *vc;
1408 struct vc_data *svc = *default_mode; 1389 struct vc_data *svc;
1409 struct fbcon_ops *ops = info->fbcon_par; 1390 struct fbcon_ops *ops = info->fbcon_par;
1410 int rows, cols, charcnt = 256; 1391 int rows, cols, charcnt = 256;
1411 1392
1393 p = &fb_display[unit];
1394
1412 if (var_to_display(p, var, info)) 1395 if (var_to_display(p, var, info))
1413 return; 1396 return;
1397
1398 vc = vc_cons[unit].d;
1399
1400 if (!vc)
1401 return;
1402
1403 default_mode = vc->vc_display_fg;
1404 svc = *default_mode;
1414 t = &fb_display[svc->vc_num]; 1405 t = &fb_display[svc->vc_num];
1406
1415 if (!vc->vc_font.data) { 1407 if (!vc->vc_font.data) {
1416 vc->vc_font.data = (void *)(p->fontdata = t->fontdata); 1408 vc->vc_font.data = (void *)(p->fontdata = t->fontdata);
1417 vc->vc_font.width = (*default_mode)->vc_font.width; 1409 vc->vc_font.width = (*default_mode)->vc_font.width;
@@ -3118,8 +3110,7 @@ static int fbcon_fb_registered(struct fb_info *info)
3118 ret = fbcon_takeover(1); 3110 ret = fbcon_takeover(1);
3119 } else { 3111 } else {
3120 for (i = first_fb_vc; i <= last_fb_vc; i++) { 3112 for (i = first_fb_vc; i <= last_fb_vc; i++) {
3121 if (con2fb_map_boot[i] == idx && 3113 if (con2fb_map_boot[i] == idx)
3122 con2fb_map[i] == -1)
3123 set_con2fb_map(i, idx, 0); 3114 set_con2fb_map(i, idx, 0);
3124 } 3115 }
3125 } 3116 }
@@ -3167,12 +3158,7 @@ static void fbcon_new_modelist(struct fb_info *info)
3167 mode = fb_find_nearest_mode(fb_display[i].mode, 3158 mode = fb_find_nearest_mode(fb_display[i].mode,
3168 &info->modelist); 3159 &info->modelist);
3169 fb_videomode_to_var(&var, mode); 3160 fb_videomode_to_var(&var, mode);
3170 3161 fbcon_set_disp(info, &var, vc->vc_num);
3171 if (vc)
3172 fbcon_set_disp(info, &var, vc);
3173 else
3174 fbcon_preset_disp(info, &var, i);
3175
3176 } 3162 }
3177} 3163}
3178 3164