]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/video/console/fbcon.c
Merge git://git.infradead.org/battery-2.6
[linux-2.6-omap-h63xx.git] / drivers / video / console / fbcon.c
index 13b67ee8b3c0eb1320c90aa585ac71e3d7bdfee5..0f32f4a00b2df52844022b4bcdac074a1f48e98c 100644 (file)
@@ -78,7 +78,6 @@
 #include <asm/fb.h>
 #include <asm/irq.h>
 #include <asm/system.h>
-#include <asm/uaccess.h>
 #ifdef CONFIG_ATARI
 #include <asm/atariints.h>
 #endif
@@ -127,8 +126,20 @@ static int last_fb_vc = MAX_NR_CONSOLES - 1;
 static int fbcon_is_default = 1; 
 static int fbcon_has_exited;
 static int primary_device = -1;
+
+#ifdef CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY
 static int map_override;
 
+static inline void fbcon_map_override(void)
+{
+       map_override = 1;
+}
+#else
+static inline void fbcon_map_override(void)
+{
+}
+#endif /* CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY */
+
 /* font data */
 static char fontname[40];
 
@@ -506,7 +517,7 @@ static int __init fb_console_setup(char *this_opt)
                                                (options[j++]-'0') % FB_MAX;
                                }
 
-                               map_override = 1;
+                               fbcon_map_override();
                        }
 
                        return 1;
@@ -2157,7 +2168,7 @@ static __inline__ void updatescrollmode(struct display *p,
 }
 
 static int fbcon_resize(struct vc_data *vc, unsigned int width, 
-                       unsigned int height)
+                       unsigned int height, unsigned int user)
 {
        struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
        struct fbcon_ops *ops = info->fbcon_par;
@@ -2394,7 +2405,7 @@ static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch)
                        update_screen(vc);
        }
 
-       if (fbcon_is_inactive(vc, info) ||
+       if (mode_switch || fbcon_is_inactive(vc, info) ||
            ops->blank_state != FB_BLANK_UNBLANK)
                fbcon_del_cursor_timer(info);
        else
@@ -3003,6 +3014,45 @@ static int fbcon_mode_deleted(struct fb_info *info,
        return found;
 }
 
+#ifdef CONFIG_VT_HW_CONSOLE_BINDING
+static int fbcon_unbind(void)
+{
+       int ret;
+
+       ret = unbind_con_driver(&fb_con, first_fb_vc, last_fb_vc,
+                               fbcon_is_default);
+       return ret;
+}
+#else
+static inline int fbcon_unbind(void)
+{
+       return -EINVAL;
+}
+#endif /* CONFIG_VT_HW_CONSOLE_BINDING */
+
+static int fbcon_fb_unbind(int idx)
+{
+       int i, new_idx = -1, ret = 0;
+
+       for (i = first_fb_vc; i <= last_fb_vc; i++) {
+               if (con2fb_map[i] != idx &&
+                   con2fb_map[i] != -1) {
+                       new_idx = i;
+                       break;
+               }
+       }
+
+       if (new_idx != -1) {
+               for (i = first_fb_vc; i <= last_fb_vc; i++) {
+                       if (con2fb_map[i] == idx)
+                               set_con2fb_map(i, new_idx, 0);
+               }
+       } else
+               ret = fbcon_unbind();
+
+       return ret;
+}
+
 static int fbcon_fb_unregistered(struct fb_info *info)
 {
        int i, idx = info->node;
@@ -3041,52 +3091,32 @@ static int fbcon_fb_unregistered(struct fb_info *info)
 }
 
 #ifdef CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY
-static int fbcon_select_primary(struct fb_info *info)
+static void fbcon_select_primary(struct fb_info *info)
 {
-       int ret = 0;
-
        if (!map_override && primary_device == -1 &&
            fb_is_primary_device(info)) {
-               int i, err;
+               int i;
 
-               printk(KERN_INFO "fbcon: %s is primary device\n",
-                      info->fix.id);
+               printk(KERN_INFO "fbcon: %s (fb%i) is primary device\n",
+                      info->fix.id, info->node);
                primary_device = info->node;
 
-               if (!con_is_bound(&fb_con))
-                       goto done;
-
-               printk(KERN_INFO "fbcon: Unbinding old driver\n");
-               unbind_con_driver(&fb_con, first_fb_vc, last_fb_vc,
-                                 fbcon_is_default);
-               info_idx = primary_device;
-
-               for (i = first_fb_vc; i <= last_fb_vc; i++) {
+               for (i = first_fb_vc; i <= last_fb_vc; i++)
                        con2fb_map_boot[i] = primary_device;
-                       con2fb_map[i] = primary_device;
-               }
-
-               printk(KERN_INFO "fbcon: Selecting new driver\n");
-               err = bind_con_driver(&fb_con, first_fb_vc, last_fb_vc,
-                                     fbcon_is_default);
-
-               if (err) {
-                       for (i = first_fb_vc; i <= last_fb_vc; i++)
-                               con2fb_map[i] = -1;
 
-                       info_idx = -1;
+               if (con_is_bound(&fb_con)) {
+                       printk(KERN_INFO "fbcon: Remapping primary device, "
+                              "fb%i, to tty %i-%i\n", info->node,
+                              first_fb_vc + 1, last_fb_vc + 1);
+                       info_idx = primary_device;
                }
-
-               ret = 1;
        }
 
-done:
-       return ret;
 }
 #else
-static inline int fbcon_select_primary(struct fb_info *info)
+static inline void fbcon_select_primary(struct fb_info *info)
 {
-       return 0;
+       return;
 }
 #endif /* CONFIG_FRAMEBUFFER_DETECT_PRIMARY */
 
@@ -3094,9 +3124,7 @@ static int fbcon_fb_registered(struct fb_info *info)
 {
        int ret = 0, i, idx = info->node;
 
-       if (fbcon_select_primary(info))
-               goto done;
-
+       fbcon_select_primary(info);
 
        if (info_idx == -1) {
                for (i = first_fb_vc; i <= last_fb_vc; i++) {
@@ -3115,7 +3143,6 @@ static int fbcon_fb_registered(struct fb_info *info)
                }
        }
 
-done:
        return ret;
 }
 
@@ -3233,6 +3260,9 @@ static int fbcon_event_notify(struct notifier_block *self,
                mode = event->data;
                ret = fbcon_mode_deleted(info, mode);
                break;
+       case FB_EVENT_FB_UNBIND:
+               ret = fbcon_fb_unbind(info->node);
+               break;
        case FB_EVENT_FB_REGISTERED:
                ret = fbcon_fb_registered(info);
                break;