Merge remote-tracking branch 'remotes/tegra/android-tegra-2.6.36-honeycomb-mr1' into...
[firefly-linux-kernel-4.4.55.git] / drivers / video / console / fbcon.c
index 807440beedb5b45386e641a72eed4e89d99a4285..7ad7e09f77d61ecab91b326b5eebb89b8389bed1 100644 (file)
@@ -283,10 +283,11 @@ static inline int fbcon_is_inactive(struct vc_data *vc, struct fb_info *info)
        struct fbcon_ops *ops = info->fbcon_par;
 
        return (info->state != FBINFO_STATE_RUNNING ||
-               vc->vc_mode != KD_TEXT || ops->graphics);
+               vc->vc_mode != KD_TEXT || ops->graphics) &&
+               !vt_force_oops_output(vc);
 }
 
-static inline int get_color(struct vc_data *vc, struct fb_info *info,
+static int get_color(struct vc_data *vc, struct fb_info *info,
              u16 c, int is_fg)
 {
        int depth = fb_get_color_depth(&info->var, &info->fix);
@@ -1073,6 +1074,7 @@ static void fbcon_init(struct vc_data *vc, int init)
        if (p->userfont)
                charcnt = FNTCHARCNT(p->fontdata);
 
+       vc->vc_panic_force_write = !!(info->flags & FBINFO_CAN_FORCE_OUTPUT);
        vc->vc_can_do_color = (fb_get_color_depth(&info->var, &info->fix)!=1);
        vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800;
        if (charcnt == 256) {
@@ -2342,6 +2344,30 @@ static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch)
        return 0;
 }
 
+static int fbcon_debug_enter(struct vc_data *vc)
+{
+       struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
+       struct fbcon_ops *ops = info->fbcon_par;
+
+       ops->save_graphics = ops->graphics;
+       ops->graphics = 0;
+       if (info->fbops->fb_debug_enter)
+               info->fbops->fb_debug_enter(info);
+       fbcon_set_palette(vc, color_table);
+       return 0;
+}
+
+static int fbcon_debug_leave(struct vc_data *vc)
+{
+       struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
+       struct fbcon_ops *ops = info->fbcon_par;
+
+       ops->graphics = ops->save_graphics;
+       if (info->fbops->fb_debug_leave)
+               info->fbops->fb_debug_leave(info);
+       return 0;
+}
+
 static int fbcon_get_font(struct vc_data *vc, struct console_font *font)
 {
        u8 *fontdata = vc->vc_font.data;
@@ -3025,6 +3051,20 @@ static int fbcon_fb_unregistered(struct fb_info *info)
        return 0;
 }
 
+static void fbcon_remap_all(int idx)
+{
+       int i;
+       for (i = first_fb_vc; i <= last_fb_vc; i++)
+               set_con2fb_map(i, idx, 0);
+
+       if (con_is_bound(&fb_con)) {
+               printk(KERN_INFO "fbcon: Remapping primary device, "
+                      "fb%i, to tty %i-%i\n", idx,
+                      first_fb_vc + 1, last_fb_vc + 1);
+               info_idx = idx;
+       }
+}
+
 #ifdef CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY
 static void fbcon_select_primary(struct fb_info *info)
 {
@@ -3225,6 +3265,10 @@ static int fbcon_event_notify(struct notifier_block *self,
                caps = event->data;
                fbcon_get_requirement(info, caps);
                break;
+       case FB_EVENT_REMAP_ALL_CONSOLE:
+               idx = info->node;
+               fbcon_remap_all(idx);
+               break;
        }
 done:
        return ret;
@@ -3258,6 +3302,8 @@ static const struct consw fb_con = {
        .con_screen_pos         = fbcon_screen_pos,
        .con_getxy              = fbcon_getxy,
        .con_resize             = fbcon_resize,
+       .con_debug_enter        = fbcon_debug_enter,
+       .con_debug_leave        = fbcon_debug_leave,
 };
 
 static struct notifier_block fbcon_event_notifier = {
@@ -3462,7 +3508,7 @@ static void fbcon_exit(void)
        softback_buf = 0UL;
 
        for (i = 0; i < FB_MAX; i++) {
-               int pending;
+               int pending = 0;
 
                mapped = 0;
                info = registered_fb[i];
@@ -3470,7 +3516,8 @@ static void fbcon_exit(void)
                if (info == NULL)
                        continue;
 
-               pending = cancel_work_sync(&info->queue);
+               if (info->queue.func)
+                       pending = cancel_work_sync(&info->queue);
                DPRINTK("fbcon: %s pending work\n", (pending ? "canceled" :
                        "no"));