Commit bd8450b9 authored by Antonino Daplas's avatar Antonino Daplas Committed by Linus Torvalds

[PATCH] Mode Switch in fbcon_blank()

As we've discussed in another thread, below is a diff that will do a set_par()
as late as possible when there is KD_TEXT<->KD_GRAPHICS switch.  The set_par()
will be forced in fbcon_resize() instead.

Not sure if this has repercussions with the other drivers, but this patch
fixed the X nv driver hanging when switching to the console.  (I believe the
crash is actually caused by an early set_par() -- while in fbcon_blank. 
Removing the set_par in fbcon_blank fixed the hang but caused cursor sprite
and display corruption).
Signed-off-by: default avatarAntonino Daplas <adaplas@pol.net>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 217f511e
...@@ -1663,7 +1663,8 @@ static int fbcon_resize(struct vc_data *vc, unsigned int width, ...@@ -1663,7 +1663,8 @@ static int fbcon_resize(struct vc_data *vc, unsigned int width,
var.yres = height * fh; var.yres = height * fh;
x_diff = info->var.xres - var.xres; x_diff = info->var.xres - var.xres;
y_diff = info->var.yres - var.yres; y_diff = info->var.yres - var.yres;
if (x_diff < 0 || x_diff > fw || (y_diff < 0 || y_diff > fh)) { if (x_diff < 0 || x_diff > fw || (y_diff < 0 || y_diff > fh) ||
(info->flags & FBINFO_MISC_MODESWITCH)) {
char mode[40]; char mode[40];
DPRINTK("attempting resize %ix%i\n", var.xres, var.yres); DPRINTK("attempting resize %ix%i\n", var.xres, var.yres);
...@@ -1678,9 +1679,12 @@ static int fbcon_resize(struct vc_data *vc, unsigned int width, ...@@ -1678,9 +1679,12 @@ static int fbcon_resize(struct vc_data *vc, unsigned int width,
return -EINVAL; return -EINVAL;
DPRINTK("resize now %ix%i\n", var.xres, var.yres); DPRINTK("resize now %ix%i\n", var.xres, var.yres);
if (CON_IS_VISIBLE(vc)) { if (CON_IS_VISIBLE(vc)) {
var.activate = FB_ACTIVATE_NOW; var.activate = FB_ACTIVATE_NOW |
(info->flags & FBINFO_MISC_MODESWITCH) ?
FB_ACTIVATE_FORCE : 0;
fb_set_var(info, &var); fb_set_var(info, &var);
} }
info->flags &= ~FBINFO_MISC_MODESWITCH;
} }
p->vrows = var.yres_virtual/fh; p->vrows = var.yres_virtual/fh;
if (var.yres > (fh * (height + 1))) if (var.yres > (fh * (height + 1)))
...@@ -1788,17 +1792,8 @@ static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch) ...@@ -1788,17 +1792,8 @@ static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch)
struct fb_info *info = registered_fb[(int) con2fb_map[vc->vc_num]]; struct fb_info *info = registered_fb[(int) con2fb_map[vc->vc_num]];
struct display *p = &fb_display[vc->vc_num]; struct display *p = &fb_display[vc->vc_num];
if (mode_switch) { if (mode_switch)
struct fb_info *info = registered_fb[(int) con2fb_map[vc->vc_num]]; info->flags |= FBINFO_MISC_MODESWITCH;
struct fb_var_screeninfo var = info->var;
if (blank) {
fbcon_cursor(vc, CM_ERASE);
return 0;
}
var.activate = FB_ACTIVATE_NOW | FB_ACTIVATE_FORCE;
fb_set_var(info, &var);
}
fbcon_cursor(vc, blank ? CM_ERASE : CM_DRAW); fbcon_cursor(vc, blank ? CM_ERASE : CM_DRAW);
......
...@@ -532,6 +532,7 @@ struct fb_ops { ...@@ -532,6 +532,7 @@ struct fb_ops {
#define FBINFO_MISC_MODECHANGEUSER 0x10000 /* mode change request #define FBINFO_MISC_MODECHANGEUSER 0x10000 /* mode change request
from userspace */ from userspace */
#define FBINFO_MISC_MODESWITCH 0x20000 /* mode switch */
struct fb_info { struct fb_info {
int node; int node;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment