Commit 1cb2c359 authored by Antonino Daplas's avatar Antonino Daplas Committed by Linus Torvalds

[PATCH] fbcon: Another fix for fbcon generic blanking code

If the driver has no fb_blank hook, then the generic method is to clear the
screen and then disallow writes to the framebuffer.  However, if the
console is leaving graphics mode (KD_GRAPHICS), it would update the screen
first, then unblank.  However, since writes to the framebuffers are
disallowed, the update failes, and upon unblank, the screen is left empty
except for the flashing cursor.  (This happens, for example when switching
from X to console).

The fix is to allow writes to the framebuffer even if the console is
blanked.  To imitate a blank screen, the get_color() function will return
the attributes of the erase character (black on black) if the console is
blanked and if the driver has no fb_blank hook.

I think this fixes the rest of the major bugs in the blanking code.  
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 8b107cbb
......@@ -203,8 +203,7 @@ static irqreturn_t fb_vbl_detect(int irq, void *dummy, struct pt_regs *fp)
static inline int fbcon_is_inactive(struct vc_data *vc, struct fb_info *info)
{
return (info->state != FBINFO_STATE_RUNNING ||
vt_cons[vc->vc_num]->vc_mode != KD_TEXT ||
(console_blanked && info->fbops->fb_blank));
vt_cons[vc->vc_num]->vc_mode != KD_TEXT);
}
static inline int get_color(struct vc_data *vc, struct fb_info *info,
......@@ -213,6 +212,12 @@ static inline int get_color(struct vc_data *vc, struct fb_info *info,
int depth = fb_get_color_depth(info);
int color = 0;
if (!info->fbops->fb_blank && console_blanked) {
unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
c = vc->vc_video_erase_char & charmask;
}
if (depth != 1)
color = (is_fg) ? attr_fgcol((vc->vc_hi_font_mask) ? 9 : 8, c)
: attr_bgcol((vc->vc_hi_font_mask) ? 13 : 12, c);
......@@ -224,6 +229,9 @@ static inline int get_color(struct vc_data *vc, struct fb_info *info,
int fg = (info->fix.visual != FB_VISUAL_MONO01) ? 1 : 0;
int bg = (info->fix.visual != FB_VISUAL_MONO01) ? 0 : 1;
if (!info->fbops->fb_blank && console_blanked)
fg = bg;
color = (is_fg) ? fg : bg;
break;
}
......@@ -244,6 +252,7 @@ static inline int get_color(struct vc_data *vc, struct fb_info *info,
break;
}
return color;
}
......@@ -1939,9 +1948,8 @@ static int fbcon_switch(struct vc_data *vc)
update_var(vc->vc_num, info);
fbcon_set_palette(vc, color_table);
fbcon_clear_margins(vc, 0);
if (vt_cons[vc->vc_num]->vc_mode == KD_TEXT)
fbcon_clear_margins(vc, 0);
if (logo_shown == FBCON_LOGO_DRAW) {
logo_shown = fg_console;
......@@ -2478,10 +2486,9 @@ static int fbcon_scrolldelta(struct vc_data *vc, int lines)
if (scrollback_current == scrollback_old)
return 0;
if (!info->fbops->fb_blank &&
(console_blanked || vt_cons[vc->vc_num]->vc_mode != KD_TEXT
|| !lines))
if (fbcon_is_inactive(vc, info))
return 0;
fbcon_cursor(vc, CM_ERASE);
offset = p->yscroll - scrollback_current;
......@@ -2510,7 +2517,7 @@ static int fbcon_scrolldelta(struct vc_data *vc, int lines)
static int fbcon_set_origin(struct vc_data *vc)
{
if (softback_lines && !console_blanked)
if (softback_lines)
fbcon_scrolldelta(vc, softback_lines);
return 0;
}
......
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