]> git.hungrycats.org Git - linux/commitdiff
[PATCH] fbcon mode switching fix
authorAntonino Daplas <adaplas@hotpop.com>
Tue, 6 Jul 2004 16:18:40 +0000 (09:18 -0700)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Tue, 6 Jul 2004 16:18:40 +0000 (09:18 -0700)
Ugly workaround.  When switching from KD_GRAPHICS to KD_TEXT, the event is
captured at fbcon_blank() allowing fbcon to reinitialize the hardware.
However, some hardware requires the reinitialization to be done
immediately, others require it to be done later.  Others may need it to be
done immediately and later, this is the worst case.

Signed-off-by: Antonino Daplas <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
drivers/video/console/fbcon.c
drivers/video/riva/fbdev.c
include/linux/fb.h

index 604b12d2b65c90ef0b4fb4db91604187fbbd1a50..f6062c285a5bd72715098f6886c3e0da32d1ef83 100644 (file)
@@ -1821,8 +1821,31 @@ 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 display *p = &fb_display[vc->vc_num];
 
-       if (mode_switch)
-               info->flags |= FBINFO_MISC_MODESWITCH;
+       if (mode_switch) {
+               struct fb_var_screeninfo var = info->var;
+
+/*
+ * HACK ALERT: Some hardware will require reinitializion at this stage,
+ *             others will require it to be done as late as possible.
+ *             For now, we differentiate this with the
+ *             FBINFO_MISC_MODESWITCHLATE bitflag.  Worst case will be
+ *             hardware that requires it here and another one later.
+ *             A definitive solution may require fixing X or the VT
+ *             system.
+ */
+               if (info->flags & FBINFO_MISC_MODESWITCHLATE)
+                       info->flags |= FBINFO_MISC_MODESWITCH;
+
+               if (blank) {
+                       fbcon_cursor(vc, CM_ERASE);
+                       return 0;
+               }
+
+               if (!(info->flags & FBINFO_MISC_MODESWITCHLATE)) {
+                       var.activate = FB_ACTIVATE_NOW | FB_ACTIVATE_FORCE;
+                       fb_set_var(info, &var);
+               }
+       }
 
        fbcon_cursor(vc, blank ? CM_ERASE : CM_DRAW);
 
index e38ae819f451be094d2d336203754e66f1a85f23..bba8aad68107fdf7909b438b5463b2c28302f456 100644 (file)
@@ -1681,7 +1681,8 @@ static int __devinit riva_set_fbinfo(struct fb_info *info)
                    | FBINFO_HWACCEL_YPAN
                    | FBINFO_HWACCEL_COPYAREA
                    | FBINFO_HWACCEL_FILLRECT
-                   | FBINFO_HWACCEL_IMAGEBLIT;
+                   | FBINFO_HWACCEL_IMAGEBLIT
+                   | FBINFO_MISC_MODESWITCHLATE;
        info->var = rivafb_default_var;
        info->fix.visual = (info->var.bits_per_pixel == 8) ?
                                FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
index fc695bb87bd61f6de68a81a479e4c5fa0047ba2d..afcdc664ddc48010f93e121cdaa18019b844a995 100644 (file)
@@ -533,6 +533,7 @@ struct fb_ops {
 #define FBINFO_MISC_MODECHANGEUSER     0x10000 /* mode change request
                                                  from userspace */
 #define FBINFO_MISC_MODESWITCH         0x20000 /* mode switch */
+#define FBINFO_MISC_MODESWITCHLATE     0x40000 /* init hardware later */
 
 struct fb_info {
        int node;