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.c375
1 files changed, 270 insertions, 105 deletions
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index 3cf1b61ff1f8..e7802ffe549a 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -107,6 +107,8 @@ enum {
107}; 107};
108 108
109struct display fb_display[MAX_NR_CONSOLES]; 109struct display fb_display[MAX_NR_CONSOLES];
110EXPORT_SYMBOL(fb_display);
111
110static signed char con2fb_map[MAX_NR_CONSOLES]; 112static signed char con2fb_map[MAX_NR_CONSOLES];
111static signed char con2fb_map_boot[MAX_NR_CONSOLES]; 113static signed char con2fb_map_boot[MAX_NR_CONSOLES];
112static int logo_height; 114static int logo_height;
@@ -130,6 +132,9 @@ static char fontname[40];
130/* current fb_info */ 132/* current fb_info */
131static int info_idx = -1; 133static int info_idx = -1;
132 134
135/* console rotation */
136static int rotate;
137
133static const struct consw fb_con; 138static const struct consw fb_con;
134 139
135#define CM_SOFTBACK (8) 140#define CM_SOFTBACK (8)
@@ -176,7 +181,6 @@ static int fbcon_scrolldelta(struct vc_data *vc, int lines);
176/* 181/*
177 * Internal routines 182 * Internal routines
178 */ 183 */
179static __inline__ int real_y(struct display *p, int ypos);
180static __inline__ void ywrap_up(struct vc_data *vc, int count); 184static __inline__ void ywrap_up(struct vc_data *vc, int count);
181static __inline__ void ywrap_down(struct vc_data *vc, int count); 185static __inline__ void ywrap_down(struct vc_data *vc, int count);
182static __inline__ void ypan_up(struct vc_data *vc, int count); 186static __inline__ void ypan_up(struct vc_data *vc, int count);
@@ -189,6 +193,8 @@ static void fbcon_preset_disp(struct fb_info *info, struct fb_var_screeninfo *va
189 int unit); 193 int unit);
190static void fbcon_redraw_move(struct vc_data *vc, struct display *p, 194static void fbcon_redraw_move(struct vc_data *vc, struct display *p,
191 int line, int count, int dy); 195 int line, int count, int dy);
196static void fbcon_modechanged(struct fb_info *info);
197static void fbcon_set_all_vcs(struct fb_info *info);
192 198
193#ifdef CONFIG_MAC 199#ifdef CONFIG_MAC
194/* 200/*
@@ -203,6 +209,88 @@ static irqreturn_t fb_vbl_detect(int irq, void *dummy, struct pt_regs *fp)
203} 209}
204#endif 210#endif
205 211
212#ifdef CONFIG_FRAMEBUFFER_CONSOLE_ROTATION
213static inline void fbcon_set_rotation(struct fb_info *info, struct display *p)
214{
215 struct fbcon_ops *ops = info->fbcon_par;
216
217 if (!(info->flags & FBINFO_MISC_TILEBLITTING) &&
218 p->con_rotate < 4)
219 ops->rotate = p->con_rotate;
220 else
221 ops->rotate = 0;
222}
223
224static void fbcon_rotate(struct fb_info *info, u32 rotate)
225{
226 struct fbcon_ops *ops= info->fbcon_par;
227 struct fb_info *fb_info;
228
229 if (!ops || ops->currcon == -1)
230 return;
231
232 fb_info = registered_fb[con2fb_map[ops->currcon]];
233
234 if (info == fb_info) {
235 struct display *p = &fb_display[ops->currcon];
236
237 if (rotate < 4)
238 p->con_rotate = rotate;
239 else
240 p->con_rotate = 0;
241
242 fbcon_modechanged(info);
243 }
244}
245
246static void fbcon_rotate_all(struct fb_info *info, u32 rotate)
247{
248 struct fbcon_ops *ops = info->fbcon_par;
249 struct vc_data *vc;
250 struct display *p;
251 int i;
252
253 if (!ops || ops->currcon < 0 || rotate > 3)
254 return;
255
256 for (i = 0; i < MAX_NR_CONSOLES; i++) {
257 vc = vc_cons[i].d;
258 if (!vc || vc->vc_mode != KD_TEXT ||
259 registered_fb[con2fb_map[i]] != info)
260 continue;
261
262 p = &fb_display[vc->vc_num];
263 p->con_rotate = rotate;
264 }
265
266 fbcon_set_all_vcs(info);
267}
268#else
269static inline void fbcon_set_rotation(struct fb_info *info, struct display *p)
270{
271 struct fbcon_ops *ops = info->fbcon_par;
272
273 ops->rotate = FB_ROTATE_UR;
274}
275
276static void fbcon_rotate(struct fb_info *info, u32 rotate)
277{
278 return;
279}
280
281static void fbcon_rotate_all(struct fb_info *info, u32 rotate)
282{
283 return;
284}
285#endif /* CONFIG_FRAMEBUFFER_CONSOLE_ROTATION */
286
287static int fbcon_get_rotate(struct fb_info *info)
288{
289 struct fbcon_ops *ops = info->fbcon_par;
290
291 return (ops) ? ops->rotate : 0;
292}
293
206static inline int fbcon_is_inactive(struct vc_data *vc, struct fb_info *info) 294static inline int fbcon_is_inactive(struct vc_data *vc, struct fb_info *info)
207{ 295{
208 struct fbcon_ops *ops = info->fbcon_par; 296 struct fbcon_ops *ops = info->fbcon_par;
@@ -422,6 +510,14 @@ static int __init fb_console_setup(char *this_opt)
422 last_fb_vc = simple_strtoul(options, &options, 10) - 1; 510 last_fb_vc = simple_strtoul(options, &options, 10) - 1;
423 fbcon_is_default = 0; 511 fbcon_is_default = 0;
424 } 512 }
513
514 if (!strncmp(options, "rotate:", 7)) {
515 options += 7;
516 if (*options)
517 rotate = simple_strtoul(options, &options, 0);
518 if (rotate > 3)
519 rotate = 0;
520 }
425 } 521 }
426 return 0; 522 return 0;
427} 523}
@@ -480,6 +576,7 @@ static void fbcon_prepare_logo(struct vc_data *vc, struct fb_info *info,
480 int cols, int rows, int new_cols, int new_rows) 576 int cols, int rows, int new_cols, int new_rows)
481{ 577{
482 /* Need to make room for the logo */ 578 /* Need to make room for the logo */
579 struct fbcon_ops *ops = info->fbcon_par;
483 int cnt, erase = vc->vc_video_erase_char, step; 580 int cnt, erase = vc->vc_video_erase_char, step;
484 unsigned short *save = NULL, *r, *q; 581 unsigned short *save = NULL, *r, *q;
485 582
@@ -489,7 +586,7 @@ static void fbcon_prepare_logo(struct vc_data *vc, struct fb_info *info,
489 */ 586 */
490 if (fb_get_color_depth(&info->var, &info->fix) == 1) 587 if (fb_get_color_depth(&info->var, &info->fix) == 1)
491 erase &= ~0x400; 588 erase &= ~0x400;
492 logo_height = fb_prepare_logo(info); 589 logo_height = fb_prepare_logo(info, ops->rotate);
493 logo_lines = (logo_height + vc->vc_font.height - 1) / 590 logo_lines = (logo_height + vc->vc_font.height - 1) /
494 vc->vc_font.height; 591 vc->vc_font.height;
495 q = (unsigned short *) (vc->vc_origin + 592 q = (unsigned short *) (vc->vc_origin +
@@ -558,16 +655,24 @@ static void set_blitting_type(struct vc_data *vc, struct fb_info *info,
558 655
559 if ((info->flags & FBINFO_MISC_TILEBLITTING)) 656 if ((info->flags & FBINFO_MISC_TILEBLITTING))
560 fbcon_set_tileops(vc, info, p, ops); 657 fbcon_set_tileops(vc, info, p, ops);
561 else 658 else {
659 struct display *disp;
660
661 disp = (p) ? p : &fb_display[vc->vc_num];
662 fbcon_set_rotation(info, disp);
562 fbcon_set_bitops(ops); 663 fbcon_set_bitops(ops);
664 }
563} 665}
564#else 666#else
565static void set_blitting_type(struct vc_data *vc, struct fb_info *info, 667static void set_blitting_type(struct vc_data *vc, struct fb_info *info,
566 struct display *p) 668 struct display *p)
567{ 669{
568 struct fbcon_ops *ops = info->fbcon_par; 670 struct fbcon_ops *ops = info->fbcon_par;
671 struct display *disp;
569 672
570 info->flags &= ~FBINFO_MISC_TILEBLITTING; 673 info->flags &= ~FBINFO_MISC_TILEBLITTING;
674 disp = (p) ? p : &fb_display[vc->vc_num];
675 fbcon_set_rotation(info, disp);
571 fbcon_set_bitops(ops); 676 fbcon_set_bitops(ops);
572} 677}
573#endif /* CONFIG_MISC_TILEBLITTING */ 678#endif /* CONFIG_MISC_TILEBLITTING */
@@ -627,6 +732,7 @@ static int con2fb_release_oldinfo(struct vc_data *vc, struct fb_info *oldinfo,
627 fbcon_del_cursor_timer(oldinfo); 732 fbcon_del_cursor_timer(oldinfo);
628 kfree(ops->cursor_state.mask); 733 kfree(ops->cursor_state.mask);
629 kfree(ops->cursor_data); 734 kfree(ops->cursor_data);
735 kfree(ops->fontbuffer);
630 kfree(oldinfo->fbcon_par); 736 kfree(oldinfo->fbcon_par);
631 oldinfo->fbcon_par = NULL; 737 oldinfo->fbcon_par = NULL;
632 module_put(oldinfo->fbops->owner); 738 module_put(oldinfo->fbops->owner);
@@ -827,7 +933,9 @@ static const char *fbcon_startup(void)
827 memset(ops, 0, sizeof(struct fbcon_ops)); 933 memset(ops, 0, sizeof(struct fbcon_ops));
828 ops->currcon = -1; 934 ops->currcon = -1;
829 ops->graphics = 1; 935 ops->graphics = 1;
936 ops->cur_rotate = -1;
830 info->fbcon_par = ops; 937 info->fbcon_par = ops;
938 p->con_rotate = rotate;
831 set_blitting_type(vc, info, NULL); 939 set_blitting_type(vc, info, NULL);
832 940
833 if (info->fix.type != FB_TYPE_TEXT) { 941 if (info->fix.type != FB_TYPE_TEXT) {
@@ -866,8 +974,10 @@ static const char *fbcon_startup(void)
866 vc->vc_font.charcount = 256; /* FIXME Need to support more fonts */ 974 vc->vc_font.charcount = 256; /* FIXME Need to support more fonts */
867 } 975 }
868 976
869 cols = info->var.xres / vc->vc_font.width; 977 cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
870 rows = info->var.yres / vc->vc_font.height; 978 rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
979 cols /= vc->vc_font.width;
980 rows /= vc->vc_font.height;
871 vc_resize(vc, cols, rows); 981 vc_resize(vc, cols, rows);
872 982
873 DPRINTK("mode: %s\n", info->fix.id); 983 DPRINTK("mode: %s\n", info->fix.id);
@@ -953,8 +1063,6 @@ static void fbcon_init(struct vc_data *vc, int init)
953 (info->fix.type == FB_TYPE_TEXT)) 1063 (info->fix.type == FB_TYPE_TEXT))
954 logo = 0; 1064 logo = 0;
955 1065
956 info->var.xoffset = info->var.yoffset = p->yscroll = 0; /* reset wrap/pan */
957
958 if (var_to_display(p, &info->var, info)) 1066 if (var_to_display(p, &info->var, info))
959 return; 1067 return;
960 1068
@@ -986,13 +1094,18 @@ static void fbcon_init(struct vc_data *vc, int init)
986 if (!*vc->vc_uni_pagedir_loc) 1094 if (!*vc->vc_uni_pagedir_loc)
987 con_copy_unimap(vc, svc); 1095 con_copy_unimap(vc, svc);
988 1096
1097 ops = info->fbcon_par;
1098 p->con_rotate = rotate;
1099 set_blitting_type(vc, info, NULL);
1100
989 cols = vc->vc_cols; 1101 cols = vc->vc_cols;
990 rows = vc->vc_rows; 1102 rows = vc->vc_rows;
991 new_cols = info->var.xres / vc->vc_font.width; 1103 new_cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
992 new_rows = info->var.yres / vc->vc_font.height; 1104 new_rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
1105 new_cols /= vc->vc_font.width;
1106 new_rows /= vc->vc_font.height;
993 vc_resize(vc, new_cols, new_rows); 1107 vc_resize(vc, new_cols, new_rows);
994 1108
995 ops = info->fbcon_par;
996 /* 1109 /*
997 * We must always set the mode. The mode of the previous console 1110 * We must always set the mode. The mode of the previous console
998 * driver could be in the same resolution but we are using different 1111 * driver could be in the same resolution but we are using different
@@ -1030,6 +1143,12 @@ static void fbcon_init(struct vc_data *vc, int init)
1030 1143
1031 if (vc == svc && softback_buf) 1144 if (vc == svc && softback_buf)
1032 fbcon_update_softback(vc); 1145 fbcon_update_softback(vc);
1146
1147 if (ops->rotate_font && ops->rotate_font(info, vc, p)) {
1148 ops->rotate = FB_ROTATE_UR;
1149 set_blitting_type(vc, info, p);
1150 }
1151
1033} 1152}
1034 1153
1035static void fbcon_deinit(struct vc_data *vc) 1154static void fbcon_deinit(struct vc_data *vc)
@@ -1066,15 +1185,6 @@ static void fbcon_deinit(struct vc_data *vc)
1066 * restriction is simplicity & efficiency at the moment. 1185 * restriction is simplicity & efficiency at the moment.
1067 */ 1186 */
1068 1187
1069static __inline__ int real_y(struct display *p, int ypos)
1070{
1071 int rows = p->vrows;
1072
1073 ypos += p->yscroll;
1074 return ypos < rows ? ypos : ypos - rows;
1075}
1076
1077
1078static void fbcon_clear(struct vc_data *vc, int sy, int sx, int height, 1188static void fbcon_clear(struct vc_data *vc, int sy, int sx, int height,
1079 int width) 1189 int width)
1080{ 1190{
@@ -1162,13 +1272,6 @@ static int scrollback_phys_max = 0;
1162static int scrollback_max = 0; 1272static int scrollback_max = 0;
1163static int scrollback_current = 0; 1273static int scrollback_current = 0;
1164 1274
1165static int update_var(int con, struct fb_info *info)
1166{
1167 if (con == ((struct fbcon_ops *)info->fbcon_par)->currcon)
1168 return fb_pan_display(info, &info->var);
1169 return 0;
1170}
1171
1172/* 1275/*
1173 * If no vc is existent yet, just set struct display 1276 * If no vc is existent yet, just set struct display
1174 */ 1277 */
@@ -1178,7 +1281,6 @@ static void fbcon_preset_disp(struct fb_info *info, struct fb_var_screeninfo *va
1178 struct display *p = &fb_display[unit]; 1281 struct display *p = &fb_display[unit];
1179 struct display *t = &fb_display[fg_console]; 1282 struct display *t = &fb_display[fg_console];
1180 1283
1181 var->xoffset = var->yoffset = p->yscroll = 0;
1182 if (var_to_display(p, var, info)) 1284 if (var_to_display(p, var, info))
1183 return; 1285 return;
1184 1286
@@ -1194,9 +1296,9 @@ static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var,
1194 struct display *p = &fb_display[vc->vc_num], *t; 1296 struct display *p = &fb_display[vc->vc_num], *t;
1195 struct vc_data **default_mode = vc->vc_display_fg; 1297 struct vc_data **default_mode = vc->vc_display_fg;
1196 struct vc_data *svc = *default_mode; 1298 struct vc_data *svc = *default_mode;
1299 struct fbcon_ops *ops = info->fbcon_par;
1197 int rows, cols, charcnt = 256; 1300 int rows, cols, charcnt = 256;
1198 1301
1199 var->xoffset = var->yoffset = p->yscroll = 0;
1200 if (var_to_display(p, var, info)) 1302 if (var_to_display(p, var, info))
1201 return; 1303 return;
1202 t = &fb_display[svc->vc_num]; 1304 t = &fb_display[svc->vc_num];
@@ -1213,9 +1315,10 @@ static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var,
1213 1315
1214 var->activate = FB_ACTIVATE_NOW; 1316 var->activate = FB_ACTIVATE_NOW;
1215 info->var.activate = var->activate; 1317 info->var.activate = var->activate;
1216 info->var.yoffset = info->var.xoffset = 0; 1318 var->yoffset = info->var.yoffset;
1319 var->xoffset = info->var.xoffset;
1217 fb_set_var(info, var); 1320 fb_set_var(info, var);
1218 1321 ops->var = info->var;
1219 vc->vc_can_do_color = (fb_get_color_depth(&info->var, &info->fix)!=1); 1322 vc->vc_can_do_color = (fb_get_color_depth(&info->var, &info->fix)!=1);
1220 vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800; 1323 vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800;
1221 if (charcnt == 256) { 1324 if (charcnt == 256) {
@@ -1231,9 +1334,12 @@ static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var,
1231 if (!*vc->vc_uni_pagedir_loc) 1334 if (!*vc->vc_uni_pagedir_loc)
1232 con_copy_unimap(vc, svc); 1335 con_copy_unimap(vc, svc);
1233 1336
1234 cols = var->xres / vc->vc_font.width; 1337 cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
1235 rows = var->yres / vc->vc_font.height; 1338 rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
1339 cols /= vc->vc_font.width;
1340 rows /= vc->vc_font.height;
1236 vc_resize(vc, cols, rows); 1341 vc_resize(vc, cols, rows);
1342
1237 if (CON_IS_VISIBLE(vc)) { 1343 if (CON_IS_VISIBLE(vc)) {
1238 update_screen(vc); 1344 update_screen(vc);
1239 if (softback_buf) 1345 if (softback_buf)
@@ -1244,15 +1350,16 @@ static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var,
1244static __inline__ void ywrap_up(struct vc_data *vc, int count) 1350static __inline__ void ywrap_up(struct vc_data *vc, int count)
1245{ 1351{
1246 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; 1352 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
1353 struct fbcon_ops *ops = info->fbcon_par;
1247 struct display *p = &fb_display[vc->vc_num]; 1354 struct display *p = &fb_display[vc->vc_num];
1248 1355
1249 p->yscroll += count; 1356 p->yscroll += count;
1250 if (p->yscroll >= p->vrows) /* Deal with wrap */ 1357 if (p->yscroll >= p->vrows) /* Deal with wrap */
1251 p->yscroll -= p->vrows; 1358 p->yscroll -= p->vrows;
1252 info->var.xoffset = 0; 1359 ops->var.xoffset = 0;
1253 info->var.yoffset = p->yscroll * vc->vc_font.height; 1360 ops->var.yoffset = p->yscroll * vc->vc_font.height;
1254 info->var.vmode |= FB_VMODE_YWRAP; 1361 ops->var.vmode |= FB_VMODE_YWRAP;
1255 update_var(vc->vc_num, info); 1362 ops->update_start(info);
1256 scrollback_max += count; 1363 scrollback_max += count;
1257 if (scrollback_max > scrollback_phys_max) 1364 if (scrollback_max > scrollback_phys_max)
1258 scrollback_max = scrollback_phys_max; 1365 scrollback_max = scrollback_phys_max;
@@ -1262,15 +1369,16 @@ static __inline__ void ywrap_up(struct vc_data *vc, int count)
1262static __inline__ void ywrap_down(struct vc_data *vc, int count) 1369static __inline__ void ywrap_down(struct vc_data *vc, int count)
1263{ 1370{
1264 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; 1371 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
1372 struct fbcon_ops *ops = info->fbcon_par;
1265 struct display *p = &fb_display[vc->vc_num]; 1373 struct display *p = &fb_display[vc->vc_num];
1266 1374
1267 p->yscroll -= count; 1375 p->yscroll -= count;
1268 if (p->yscroll < 0) /* Deal with wrap */ 1376 if (p->yscroll < 0) /* Deal with wrap */
1269 p->yscroll += p->vrows; 1377 p->yscroll += p->vrows;
1270 info->var.xoffset = 0; 1378 ops->var.xoffset = 0;
1271 info->var.yoffset = p->yscroll * vc->vc_font.height; 1379 ops->var.yoffset = p->yscroll * vc->vc_font.height;
1272 info->var.vmode |= FB_VMODE_YWRAP; 1380 ops->var.vmode |= FB_VMODE_YWRAP;
1273 update_var(vc->vc_num, info); 1381 ops->update_start(info);
1274 scrollback_max -= count; 1382 scrollback_max -= count;
1275 if (scrollback_max < 0) 1383 if (scrollback_max < 0)
1276 scrollback_max = 0; 1384 scrollback_max = 0;
@@ -1289,10 +1397,11 @@ static __inline__ void ypan_up(struct vc_data *vc, int count)
1289 0, 0, 0, vc->vc_rows, vc->vc_cols); 1397 0, 0, 0, vc->vc_rows, vc->vc_cols);
1290 p->yscroll -= p->vrows - vc->vc_rows; 1398 p->yscroll -= p->vrows - vc->vc_rows;
1291 } 1399 }
1292 info->var.xoffset = 0; 1400
1293 info->var.yoffset = p->yscroll * vc->vc_font.height; 1401 ops->var.xoffset = 0;
1294 info->var.vmode &= ~FB_VMODE_YWRAP; 1402 ops->var.yoffset = p->yscroll * vc->vc_font.height;
1295 update_var(vc->vc_num, info); 1403 ops->var.vmode &= ~FB_VMODE_YWRAP;
1404 ops->update_start(info);
1296 fbcon_clear_margins(vc, 1); 1405 fbcon_clear_margins(vc, 1);
1297 scrollback_max += count; 1406 scrollback_max += count;
1298 if (scrollback_max > scrollback_phys_max) 1407 if (scrollback_max > scrollback_phys_max)
@@ -1303,6 +1412,7 @@ static __inline__ void ypan_up(struct vc_data *vc, int count)
1303static __inline__ void ypan_up_redraw(struct vc_data *vc, int t, int count) 1412static __inline__ void ypan_up_redraw(struct vc_data *vc, int t, int count)
1304{ 1413{
1305 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; 1414 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
1415 struct fbcon_ops *ops = info->fbcon_par;
1306 struct display *p = &fb_display[vc->vc_num]; 1416 struct display *p = &fb_display[vc->vc_num];
1307 int redraw = 0; 1417 int redraw = 0;
1308 1418
@@ -1312,12 +1422,13 @@ static __inline__ void ypan_up_redraw(struct vc_data *vc, int t, int count)
1312 redraw = 1; 1422 redraw = 1;
1313 } 1423 }
1314 1424
1315 info->var.xoffset = 0;
1316 info->var.yoffset = p->yscroll * vc->vc_font.height;
1317 info->var.vmode &= ~FB_VMODE_YWRAP;
1318 if (redraw) 1425 if (redraw)
1319 fbcon_redraw_move(vc, p, t + count, vc->vc_rows - count, t); 1426 fbcon_redraw_move(vc, p, t + count, vc->vc_rows - count, t);
1320 update_var(vc->vc_num, info); 1427
1428 ops->var.xoffset = 0;
1429 ops->var.yoffset = p->yscroll * vc->vc_font.height;
1430 ops->var.vmode &= ~FB_VMODE_YWRAP;
1431 ops->update_start(info);
1321 fbcon_clear_margins(vc, 1); 1432 fbcon_clear_margins(vc, 1);
1322 scrollback_max += count; 1433 scrollback_max += count;
1323 if (scrollback_max > scrollback_phys_max) 1434 if (scrollback_max > scrollback_phys_max)
@@ -1337,10 +1448,11 @@ static __inline__ void ypan_down(struct vc_data *vc, int count)
1337 0, vc->vc_rows, vc->vc_cols); 1448 0, vc->vc_rows, vc->vc_cols);
1338 p->yscroll += p->vrows - vc->vc_rows; 1449 p->yscroll += p->vrows - vc->vc_rows;
1339 } 1450 }
1340 info->var.xoffset = 0; 1451
1341 info->var.yoffset = p->yscroll * vc->vc_font.height; 1452 ops->var.xoffset = 0;
1342 info->var.vmode &= ~FB_VMODE_YWRAP; 1453 ops->var.yoffset = p->yscroll * vc->vc_font.height;
1343 update_var(vc->vc_num, info); 1454 ops->var.vmode &= ~FB_VMODE_YWRAP;
1455 ops->update_start(info);
1344 fbcon_clear_margins(vc, 1); 1456 fbcon_clear_margins(vc, 1);
1345 scrollback_max -= count; 1457 scrollback_max -= count;
1346 if (scrollback_max < 0) 1458 if (scrollback_max < 0)
@@ -1351,6 +1463,7 @@ static __inline__ void ypan_down(struct vc_data *vc, int count)
1351static __inline__ void ypan_down_redraw(struct vc_data *vc, int t, int count) 1463static __inline__ void ypan_down_redraw(struct vc_data *vc, int t, int count)
1352{ 1464{
1353 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; 1465 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
1466 struct fbcon_ops *ops = info->fbcon_par;
1354 struct display *p = &fb_display[vc->vc_num]; 1467 struct display *p = &fb_display[vc->vc_num];
1355 int redraw = 0; 1468 int redraw = 0;
1356 1469
@@ -1359,12 +1472,14 @@ static __inline__ void ypan_down_redraw(struct vc_data *vc, int t, int count)
1359 p->yscroll += p->vrows - vc->vc_rows; 1472 p->yscroll += p->vrows - vc->vc_rows;
1360 redraw = 1; 1473 redraw = 1;
1361 } 1474 }
1362 info->var.xoffset = 0; 1475
1363 info->var.yoffset = p->yscroll * vc->vc_font.height;
1364 info->var.vmode &= ~FB_VMODE_YWRAP;
1365 if (redraw) 1476 if (redraw)
1366 fbcon_redraw_move(vc, p, t, vc->vc_rows - count, t + count); 1477 fbcon_redraw_move(vc, p, t, vc->vc_rows - count, t + count);
1367 update_var(vc->vc_num, info); 1478
1479 ops->var.xoffset = 0;
1480 ops->var.yoffset = p->yscroll * vc->vc_font.height;
1481 ops->var.vmode &= ~FB_VMODE_YWRAP;
1482 ops->update_start(info);
1368 fbcon_clear_margins(vc, 1); 1483 fbcon_clear_margins(vc, 1);
1369 scrollback_max -= count; 1484 scrollback_max -= count;
1370 if (scrollback_max < 0) 1485 if (scrollback_max < 0)
@@ -1838,31 +1953,41 @@ static void fbcon_bmove_rec(struct vc_data *vc, struct display *p, int sy, int s
1838 height, width); 1953 height, width);
1839} 1954}
1840 1955
1841static __inline__ void updatescrollmode(struct display *p, struct fb_info *info, 1956static __inline__ void updatescrollmode(struct display *p,
1957 struct fb_info *info,
1842 struct vc_data *vc) 1958 struct vc_data *vc)
1843{ 1959{
1960 struct fbcon_ops *ops = info->fbcon_par;
1844 int fh = vc->vc_font.height; 1961 int fh = vc->vc_font.height;
1845 int cap = info->flags; 1962 int cap = info->flags;
1846 int good_pan = (cap & FBINFO_HWACCEL_YPAN) 1963 u16 t = 0;
1847 && divides(info->fix.ypanstep, vc->vc_font.height) 1964 int ypan = FBCON_SWAP(ops->rotate, info->fix.ypanstep,
1848 && info->var.yres_virtual > info->var.yres; 1965 info->fix.xpanstep);
1849 int good_wrap = (cap & FBINFO_HWACCEL_YWRAP) 1966 int ywrap = FBCON_SWAP(ops->rotate, info->fix.ywrapstep, t);
1850 && divides(info->fix.ywrapstep, vc->vc_font.height) 1967 int yres = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
1851 && divides(vc->vc_font.height, info->var.yres_virtual); 1968 int vyres = FBCON_SWAP(ops->rotate, info->var.yres_virtual,
1969 info->var.xres_virtual);
1970 int good_pan = (cap & FBINFO_HWACCEL_YPAN) &&
1971 divides(ypan, vc->vc_font.height) && vyres > yres;
1972 int good_wrap = (cap & FBINFO_HWACCEL_YWRAP) &&
1973 divides(ywrap, vc->vc_font.height) &&
1974 divides(vc->vc_font.height, vyres);
1852 int reading_fast = cap & FBINFO_READS_FAST; 1975 int reading_fast = cap & FBINFO_READS_FAST;
1853 int fast_copyarea = (cap & FBINFO_HWACCEL_COPYAREA) && !(cap & FBINFO_HWACCEL_DISABLED); 1976 int fast_copyarea = (cap & FBINFO_HWACCEL_COPYAREA) &&
1854 int fast_imageblit = (cap & FBINFO_HWACCEL_IMAGEBLIT) && !(cap & FBINFO_HWACCEL_DISABLED); 1977 !(cap & FBINFO_HWACCEL_DISABLED);
1855 1978 int fast_imageblit = (cap & FBINFO_HWACCEL_IMAGEBLIT) &&
1856 p->vrows = info->var.yres_virtual/fh; 1979 !(cap & FBINFO_HWACCEL_DISABLED);
1857 if (info->var.yres > (fh * (vc->vc_rows + 1))) 1980
1858 p->vrows -= (info->var.yres - (fh * vc->vc_rows)) / fh; 1981 p->vrows = vyres/fh;
1859 if ((info->var.yres % fh) && (info->var.yres_virtual % fh < 1982 if (yres > (fh * (vc->vc_rows + 1)))
1860 info->var.yres % fh)) 1983 p->vrows -= (yres - (fh * vc->vc_rows)) / fh;
1984 if ((yres % fh) && (vyres % fh < yres % fh))
1861 p->vrows--; 1985 p->vrows--;
1862 1986
1863 if (good_wrap || good_pan) { 1987 if (good_wrap || good_pan) {
1864 if (reading_fast || fast_copyarea) 1988 if (reading_fast || fast_copyarea)
1865 p->scrollmode = good_wrap ? SCROLL_WRAP_MOVE : SCROLL_PAN_MOVE; 1989 p->scrollmode = good_wrap ?
1990 SCROLL_WRAP_MOVE : SCROLL_PAN_MOVE;
1866 else 1991 else
1867 p->scrollmode = good_wrap ? SCROLL_REDRAW : 1992 p->scrollmode = good_wrap ? SCROLL_REDRAW :
1868 SCROLL_PAN_REDRAW; 1993 SCROLL_PAN_REDRAW;
@@ -1878,17 +2003,23 @@ static int fbcon_resize(struct vc_data *vc, unsigned int width,
1878 unsigned int height) 2003 unsigned int height)
1879{ 2004{
1880 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; 2005 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
2006 struct fbcon_ops *ops = info->fbcon_par;
1881 struct display *p = &fb_display[vc->vc_num]; 2007 struct display *p = &fb_display[vc->vc_num];
1882 struct fb_var_screeninfo var = info->var; 2008 struct fb_var_screeninfo var = info->var;
1883 int x_diff, y_diff; 2009 int x_diff, y_diff, virt_w, virt_h, virt_fw, virt_fh;
1884 int fw = vc->vc_font.width; 2010
1885 int fh = vc->vc_font.height; 2011 virt_w = FBCON_SWAP(ops->rotate, width, height);
1886 2012 virt_h = FBCON_SWAP(ops->rotate, height, width);
1887 var.xres = width * fw; 2013 virt_fw = FBCON_SWAP(ops->rotate, vc->vc_font.width,
1888 var.yres = height * fh; 2014 vc->vc_font.height);
2015 virt_fh = FBCON_SWAP(ops->rotate, vc->vc_font.height,
2016 vc->vc_font.width);
2017 var.xres = virt_w * virt_fw;
2018 var.yres = virt_h * virt_fh;
1889 x_diff = info->var.xres - var.xres; 2019 x_diff = info->var.xres - var.xres;
1890 y_diff = info->var.yres - var.yres; 2020 y_diff = info->var.yres - var.yres;
1891 if (x_diff < 0 || x_diff > fw || (y_diff < 0 || y_diff > fh)) { 2021 if (x_diff < 0 || x_diff > virt_fw ||
2022 y_diff < 0 || y_diff > virt_fh) {
1892 struct fb_videomode *mode; 2023 struct fb_videomode *mode;
1893 2024
1894 DPRINTK("attempting resize %ix%i\n", var.xres, var.yres); 2025 DPRINTK("attempting resize %ix%i\n", var.xres, var.yres);
@@ -1898,7 +2029,7 @@ static int fbcon_resize(struct vc_data *vc, unsigned int width,
1898 display_to_var(&var, p); 2029 display_to_var(&var, p);
1899 fb_videomode_to_var(&var, mode); 2030 fb_videomode_to_var(&var, mode);
1900 2031
1901 if (width > var.xres/fw || height > var.yres/fh) 2032 if (virt_w > var.xres/virt_fw || virt_h > var.yres/virt_fh)
1902 return -EINVAL; 2033 return -EINVAL;
1903 2034
1904 DPRINTK("resize now %ix%i\n", var.xres, var.yres); 2035 DPRINTK("resize now %ix%i\n", var.xres, var.yres);
@@ -1908,6 +2039,7 @@ static int fbcon_resize(struct vc_data *vc, unsigned int width,
1908 fb_set_var(info, &var); 2039 fb_set_var(info, &var);
1909 } 2040 }
1910 var_to_display(p, &info->var, info); 2041 var_to_display(p, &info->var, info);
2042 ops->var = info->var;
1911 } 2043 }
1912 updatescrollmode(p, info, vc); 2044 updatescrollmode(p, info, vc);
1913 return 0; 2045 return 0;
@@ -1916,11 +2048,13 @@ static int fbcon_resize(struct vc_data *vc, unsigned int width,
1916static int fbcon_switch(struct vc_data *vc) 2048static int fbcon_switch(struct vc_data *vc)
1917{ 2049{
1918 struct fb_info *info, *old_info = NULL; 2050 struct fb_info *info, *old_info = NULL;
2051 struct fbcon_ops *ops;
1919 struct display *p = &fb_display[vc->vc_num]; 2052 struct display *p = &fb_display[vc->vc_num];
1920 struct fb_var_screeninfo var; 2053 struct fb_var_screeninfo var;
1921 int i, prev_console; 2054 int i, prev_console;
1922 2055
1923 info = registered_fb[con2fb_map[vc->vc_num]]; 2056 info = registered_fb[con2fb_map[vc->vc_num]];
2057 ops = info->fbcon_par;
1924 2058
1925 if (softback_top) { 2059 if (softback_top) {
1926 if (softback_lines) 2060 if (softback_lines)
@@ -1939,7 +2073,7 @@ static int fbcon_switch(struct vc_data *vc)
1939 logo_shown = FBCON_LOGO_CANSHOW; 2073 logo_shown = FBCON_LOGO_CANSHOW;
1940 } 2074 }
1941 2075
1942 prev_console = ((struct fbcon_ops *)info->fbcon_par)->currcon; 2076 prev_console = ops->currcon;
1943 if (prev_console != -1) 2077 if (prev_console != -1)
1944 old_info = registered_fb[con2fb_map[prev_console]]; 2078 old_info = registered_fb[con2fb_map[prev_console]];
1945 /* 2079 /*
@@ -1952,9 +2086,9 @@ static int fbcon_switch(struct vc_data *vc)
1952 */ 2086 */
1953 for (i = 0; i < FB_MAX; i++) { 2087 for (i = 0; i < FB_MAX; i++) {
1954 if (registered_fb[i] != NULL && registered_fb[i]->fbcon_par) { 2088 if (registered_fb[i] != NULL && registered_fb[i]->fbcon_par) {
1955 struct fbcon_ops *ops = registered_fb[i]->fbcon_par; 2089 struct fbcon_ops *o = registered_fb[i]->fbcon_par;
1956 2090
1957 ops->currcon = vc->vc_num; 2091 o->currcon = vc->vc_num;
1958 } 2092 }
1959 } 2093 }
1960 memset(&var, 0, sizeof(struct fb_var_screeninfo)); 2094 memset(&var, 0, sizeof(struct fb_var_screeninfo));
@@ -1966,8 +2100,11 @@ static int fbcon_switch(struct vc_data *vc)
1966 * in fb_set_var() 2100 * in fb_set_var()
1967 */ 2101 */
1968 info->var.activate = var.activate; 2102 info->var.activate = var.activate;
1969 info->var.yoffset = info->var.xoffset = p->yscroll = 0; 2103 var.yoffset = info->var.yoffset;
2104 var.xoffset = info->var.xoffset;
2105 var.vmode = info->var.vmode;
1970 fb_set_var(info, &var); 2106 fb_set_var(info, &var);
2107 ops->var = info->var;
1971 2108
1972 if (old_info != NULL && old_info != info) { 2109 if (old_info != NULL && old_info != info) {
1973 if (info->fbops->fb_set_par) 2110 if (info->fbops->fb_set_par)
@@ -1977,7 +2114,12 @@ static int fbcon_switch(struct vc_data *vc)
1977 } 2114 }
1978 2115
1979 set_blitting_type(vc, info, p); 2116 set_blitting_type(vc, info, p);
1980 ((struct fbcon_ops *)info->fbcon_par)->cursor_reset = 1; 2117 ops->cursor_reset = 1;
2118
2119 if (ops->rotate_font && ops->rotate_font(info, vc, p)) {
2120 ops->rotate = FB_ROTATE_UR;
2121 set_blitting_type(vc, info, p);
2122 }
1981 2123
1982 vc->vc_can_do_color = (fb_get_color_depth(&info->var, &info->fix)!=1); 2124 vc->vc_can_do_color = (fb_get_color_depth(&info->var, &info->fix)!=1);
1983 vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800; 2125 vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800;
@@ -1997,10 +2139,11 @@ static int fbcon_switch(struct vc_data *vc)
1997 scrollback_phys_max = 0; 2139 scrollback_phys_max = 0;
1998 break; 2140 break;
1999 } 2141 }
2142
2000 scrollback_max = 0; 2143 scrollback_max = 0;
2001 scrollback_current = 0; 2144 scrollback_current = 0;
2002 2145 ops->var.xoffset = ops->var.yoffset = p->yscroll = 0;
2003 update_var(vc->vc_num, info); 2146 ops->update_start(info);
2004 fbcon_set_palette(vc, color_table); 2147 fbcon_set_palette(vc, color_table);
2005 fbcon_clear_margins(vc, 0); 2148 fbcon_clear_margins(vc, 0);
2006 2149
@@ -2008,7 +2151,7 @@ static int fbcon_switch(struct vc_data *vc)
2008 2151
2009 logo_shown = fg_console; 2152 logo_shown = fg_console;
2010 /* This is protected above by initmem_freed */ 2153 /* This is protected above by initmem_freed */
2011 fb_show_logo(info); 2154 fb_show_logo(info, ops->rotate);
2012 update_region(vc, 2155 update_region(vc,
2013 vc->vc_origin + vc->vc_size_row * vc->vc_top, 2156 vc->vc_origin + vc->vc_size_row * vc->vc_top,
2014 vc->vc_size_row * (vc->vc_bottom - 2157 vc->vc_size_row * (vc->vc_bottom -
@@ -2047,6 +2190,7 @@ static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch)
2047 var.activate = FB_ACTIVATE_NOW | FB_ACTIVATE_FORCE; 2190 var.activate = FB_ACTIVATE_NOW | FB_ACTIVATE_FORCE;
2048 fb_set_var(info, &var); 2191 fb_set_var(info, &var);
2049 ops->graphics = 0; 2192 ops->graphics = 0;
2193 ops->var = info->var;
2050 } 2194 }
2051 } 2195 }
2052 2196
@@ -2135,6 +2279,7 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h,
2135 const u8 * data, int userfont) 2279 const u8 * data, int userfont)
2136{ 2280{
2137 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; 2281 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
2282 struct fbcon_ops *ops = info->fbcon_par;
2138 struct display *p = &fb_display[vc->vc_num]; 2283 struct display *p = &fb_display[vc->vc_num];
2139 int resize; 2284 int resize;
2140 int cnt; 2285 int cnt;
@@ -2214,9 +2359,13 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h,
2214 } 2359 }
2215 2360
2216 if (resize) { 2361 if (resize) {
2217 /* reset wrap/pan */ 2362 int cols, rows;
2218 info->var.xoffset = info->var.yoffset = p->yscroll = 0; 2363
2219 vc_resize(vc, info->var.xres / w, info->var.yres / h); 2364 cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
2365 rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
2366 cols /= w;
2367 rows /= h;
2368 vc_resize(vc, cols, rows);
2220 if (CON_IS_VISIBLE(vc) && softback_buf) 2369 if (CON_IS_VISIBLE(vc) && softback_buf)
2221 fbcon_update_softback(vc); 2370 fbcon_update_softback(vc);
2222 } else if (CON_IS_VISIBLE(vc) 2371 } else if (CON_IS_VISIBLE(vc)
@@ -2444,6 +2593,7 @@ static void fbcon_invert_region(struct vc_data *vc, u16 * p, int cnt)
2444static int fbcon_scrolldelta(struct vc_data *vc, int lines) 2593static int fbcon_scrolldelta(struct vc_data *vc, int lines)
2445{ 2594{
2446 struct fb_info *info = registered_fb[con2fb_map[fg_console]]; 2595 struct fb_info *info = registered_fb[con2fb_map[fg_console]];
2596 struct fbcon_ops *ops = info->fbcon_par;
2447 struct display *p = &fb_display[fg_console]; 2597 struct display *p = &fb_display[fg_console];
2448 int offset, limit, scrollback_old; 2598 int offset, limit, scrollback_old;
2449 2599
@@ -2520,9 +2670,11 @@ static int fbcon_scrolldelta(struct vc_data *vc, int lines)
2520 offset += limit; 2670 offset += limit;
2521 else if (offset >= limit) 2671 else if (offset >= limit)
2522 offset -= limit; 2672 offset -= limit;
2523 info->var.xoffset = 0; 2673
2524 info->var.yoffset = offset * vc->vc_font.height; 2674 ops->var.xoffset = 0;
2525 update_var(vc->vc_num, info); 2675 ops->var.yoffset = offset * vc->vc_font.height;
2676 ops->update_start(info);
2677
2526 if (!scrollback_current) 2678 if (!scrollback_current)
2527 fbcon_cursor(vc, CM_DRAW); 2679 fbcon_cursor(vc, CM_DRAW);
2528 return 0; 2680 return 0;
@@ -2570,22 +2722,25 @@ static void fbcon_modechanged(struct fb_info *info)
2570 if (!ops || ops->currcon < 0) 2722 if (!ops || ops->currcon < 0)
2571 return; 2723 return;
2572 vc = vc_cons[ops->currcon].d; 2724 vc = vc_cons[ops->currcon].d;
2573 if (vc->vc_mode != KD_TEXT || registered_fb[con2fb_map[ops->currcon]] != info) 2725 if (vc->vc_mode != KD_TEXT ||
2726 registered_fb[con2fb_map[ops->currcon]] != info)
2574 return; 2727 return;
2575 2728
2576 p = &fb_display[vc->vc_num]; 2729 p = &fb_display[vc->vc_num];
2577 2730 set_blitting_type(vc, info, p);
2578 info->var.xoffset = info->var.yoffset = p->yscroll = 0;
2579 2731
2580 if (CON_IS_VISIBLE(vc)) { 2732 if (CON_IS_VISIBLE(vc)) {
2581 var_to_display(p, &info->var, info); 2733 var_to_display(p, &info->var, info);
2582 cols = info->var.xres / vc->vc_font.width; 2734 cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
2583 rows = info->var.yres / vc->vc_font.height; 2735 rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
2736 cols /= vc->vc_font.width;
2737 rows /= vc->vc_font.height;
2584 vc_resize(vc, cols, rows); 2738 vc_resize(vc, cols, rows);
2585 updatescrollmode(p, info, vc); 2739 updatescrollmode(p, info, vc);
2586 scrollback_max = 0; 2740 scrollback_max = 0;
2587 scrollback_current = 0; 2741 scrollback_current = 0;
2588 update_var(vc->vc_num, info); 2742 ops->var.xoffset = ops->var.yoffset = p->yscroll = 0;
2743 ops->update_start(info);
2589 fbcon_set_palette(vc, color_table); 2744 fbcon_set_palette(vc, color_table);
2590 update_screen(vc); 2745 update_screen(vc);
2591 if (softback_buf) 2746 if (softback_buf)
@@ -2610,18 +2765,20 @@ static void fbcon_set_all_vcs(struct fb_info *info)
2610 continue; 2765 continue;
2611 2766
2612 p = &fb_display[vc->vc_num]; 2767 p = &fb_display[vc->vc_num];
2613 2768 set_blitting_type(vc, info, p);
2614 info->var.xoffset = info->var.yoffset = p->yscroll = 0;
2615 var_to_display(p, &info->var, info); 2769 var_to_display(p, &info->var, info);
2616 cols = info->var.xres / vc->vc_font.width; 2770 cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
2617 rows = info->var.yres / vc->vc_font.height; 2771 rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
2772 cols /= vc->vc_font.width;
2773 rows /= vc->vc_font.height;
2618 vc_resize(vc, cols, rows); 2774 vc_resize(vc, cols, rows);
2619 2775
2620 if (CON_IS_VISIBLE(vc)) { 2776 if (CON_IS_VISIBLE(vc)) {
2621 updatescrollmode(p, info, vc); 2777 updatescrollmode(p, info, vc);
2622 scrollback_max = 0; 2778 scrollback_max = 0;
2623 scrollback_current = 0; 2779 scrollback_current = 0;
2624 update_var(vc->vc_num, info); 2780 ops->var.xoffset = ops->var.yoffset = p->yscroll = 0;
2781 ops->update_start(info);
2625 fbcon_set_palette(vc, color_table); 2782 fbcon_set_palette(vc, color_table);
2626 update_screen(vc); 2783 update_screen(vc);
2627 if (softback_buf) 2784 if (softback_buf)
@@ -2771,6 +2928,14 @@ static int fbcon_event_notify(struct notifier_block *self,
2771 case FB_EVENT_NEW_MODELIST: 2928 case FB_EVENT_NEW_MODELIST:
2772 fbcon_new_modelist(info); 2929 fbcon_new_modelist(info);
2773 break; 2930 break;
2931 case FB_EVENT_SET_CON_ROTATE:
2932 fbcon_rotate(info, *(int *)event->data);
2933 break;
2934 case FB_EVENT_GET_CON_ROTATE:
2935 ret = fbcon_get_rotate(info);
2936 break;
2937 case FB_EVENT_SET_CON_ROTATE_ALL:
2938 fbcon_rotate_all(info, *(int *)event->data);
2774 } 2939 }
2775 2940
2776 return ret; 2941 return ret;