From: "Antonino A. Daplas" <adaplas@hotpop.com>

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: Antonino Daplas <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 25-akpm/drivers/video/console/fbcon.c |   23 +++++++++++++++--------
 1 files changed, 15 insertions(+), 8 deletions(-)

diff -puN drivers/video/console/fbcon.c~fbcon-another-fix-for-fbcon-generic-blanking-code drivers/video/console/fbcon.c
--- 25/drivers/video/console/fbcon.c~fbcon-another-fix-for-fbcon-generic-blanking-code	2004-11-04 00:58:59.956496808 -0800
+++ 25-akpm/drivers/video/console/fbcon.c	2004-11-04 00:58:59.962495896 -0800
@@ -203,8 +203,7 @@ static irqreturn_t fb_vbl_detect(int irq
 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_da
 	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_da
 		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_da
 		break;
 	}
 
+
 	return color;
 }
 
@@ -1939,9 +1948,8 @@ static int fbcon_switch(struct vc_data *
 
 	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_d
 	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_d
 
 static int fbcon_set_origin(struct vc_data *vc)
 {
-	if (softback_lines && !console_blanked)
+	if (softback_lines)
 		fbcon_scrolldelta(vc, softback_lines);
 	return 0;
 }
_