diff options
-rw-r--r-- | drivers/char/vt.c | 13 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_fb.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_fbcon.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_fb.c | 2 | ||||
-rw-r--r-- | drivers/video/console/fbcon.c | 4 | ||||
-rw-r--r-- | include/linux/console_struct.h | 1 | ||||
-rw-r--r-- | include/linux/fb.h | 4 | ||||
-rw-r--r-- | include/linux/vt_kern.h | 7 |
8 files changed, 27 insertions, 9 deletions
diff --git a/drivers/char/vt.c b/drivers/char/vt.c index 34bfb056d7a6..82f64ac21191 100644 --- a/drivers/char/vt.c +++ b/drivers/char/vt.c | |||
@@ -705,7 +705,10 @@ void redraw_screen(struct vc_data *vc, int is_switch) | |||
705 | update_attr(vc); | 705 | update_attr(vc); |
706 | clear_buffer_attributes(vc); | 706 | clear_buffer_attributes(vc); |
707 | } | 707 | } |
708 | if (update && vc->vc_mode != KD_GRAPHICS) | 708 | |
709 | /* Forcibly update if we're panicing */ | ||
710 | if ((update && vc->vc_mode != KD_GRAPHICS) || | ||
711 | vt_force_oops_output(vc)) | ||
709 | do_update_region(vc, vc->vc_origin, vc->vc_screenbuf_size / 2); | 712 | do_update_region(vc, vc->vc_origin, vc->vc_screenbuf_size / 2); |
710 | } | 713 | } |
711 | set_cursor(vc); | 714 | set_cursor(vc); |
@@ -743,6 +746,7 @@ static void visual_init(struct vc_data *vc, int num, int init) | |||
743 | vc->vc_hi_font_mask = 0; | 746 | vc->vc_hi_font_mask = 0; |
744 | vc->vc_complement_mask = 0; | 747 | vc->vc_complement_mask = 0; |
745 | vc->vc_can_do_color = 0; | 748 | vc->vc_can_do_color = 0; |
749 | vc->vc_panic_force_write = false; | ||
746 | vc->vc_sw->con_init(vc, init); | 750 | vc->vc_sw->con_init(vc, init); |
747 | if (!vc->vc_complement_mask) | 751 | if (!vc->vc_complement_mask) |
748 | vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800; | 752 | vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800; |
@@ -2506,7 +2510,7 @@ static void vt_console_print(struct console *co, const char *b, unsigned count) | |||
2506 | goto quit; | 2510 | goto quit; |
2507 | } | 2511 | } |
2508 | 2512 | ||
2509 | if (vc->vc_mode != KD_TEXT) | 2513 | if (vc->vc_mode != KD_TEXT && !vt_force_oops_output(vc)) |
2510 | goto quit; | 2514 | goto quit; |
2511 | 2515 | ||
2512 | /* undraw cursor first */ | 2516 | /* undraw cursor first */ |
@@ -3784,7 +3788,8 @@ void do_unblank_screen(int leaving_gfx) | |||
3784 | return; | 3788 | return; |
3785 | } | 3789 | } |
3786 | vc = vc_cons[fg_console].d; | 3790 | vc = vc_cons[fg_console].d; |
3787 | if (vc->vc_mode != KD_TEXT) | 3791 | /* Try to unblank in oops case too */ |
3792 | if (vc->vc_mode != KD_TEXT && !vt_force_oops_output(vc)) | ||
3788 | return; /* but leave console_blanked != 0 */ | 3793 | return; /* but leave console_blanked != 0 */ |
3789 | 3794 | ||
3790 | if (blankinterval) { | 3795 | if (blankinterval) { |
@@ -3793,7 +3798,7 @@ void do_unblank_screen(int leaving_gfx) | |||
3793 | } | 3798 | } |
3794 | 3799 | ||
3795 | console_blanked = 0; | 3800 | console_blanked = 0; |
3796 | if (vc->vc_sw->con_blank(vc, 0, leaving_gfx)) | 3801 | if (vc->vc_sw->con_blank(vc, 0, leaving_gfx) || vt_force_oops_output(vc)) |
3797 | /* Low-level driver cannot restore -> do it ourselves */ | 3802 | /* Low-level driver cannot restore -> do it ourselves */ |
3798 | update_screen(vc); | 3803 | update_screen(vc); |
3799 | if (console_blank_hook) | 3804 | if (console_blank_hook) |
diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c index 54acd8b534df..a79525f434a8 100644 --- a/drivers/gpu/drm/i915/intel_fb.c +++ b/drivers/gpu/drm/i915/intel_fb.c | |||
@@ -130,7 +130,7 @@ static int intelfb_create(struct intel_fbdev *ifbdev, | |||
130 | 130 | ||
131 | strcpy(info->fix.id, "inteldrmfb"); | 131 | strcpy(info->fix.id, "inteldrmfb"); |
132 | 132 | ||
133 | info->flags = FBINFO_DEFAULT; | 133 | info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT; |
134 | info->fbops = &intelfb_ops; | 134 | info->fbops = &intelfb_ops; |
135 | 135 | ||
136 | /* setup aperture base/size for vesafb takeover */ | 136 | /* setup aperture base/size for vesafb takeover */ |
@@ -148,8 +148,6 @@ static int intelfb_create(struct intel_fbdev *ifbdev, | |||
148 | info->fix.smem_start = dev->mode_config.fb_base + obj_priv->gtt_offset; | 148 | info->fix.smem_start = dev->mode_config.fb_base + obj_priv->gtt_offset; |
149 | info->fix.smem_len = size; | 149 | info->fix.smem_len = size; |
150 | 150 | ||
151 | info->flags = FBINFO_DEFAULT; | ||
152 | |||
153 | info->screen_base = ioremap_wc(dev->agp->base + obj_priv->gtt_offset, | 151 | info->screen_base = ioremap_wc(dev->agp->base + obj_priv->gtt_offset, |
154 | size); | 152 | size); |
155 | if (!info->screen_base) { | 153 | if (!info->screen_base) { |
diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c index 2fb2444d2322..099f637264aa 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c | |||
@@ -250,6 +250,7 @@ nouveau_fbcon_create(struct nouveau_fbdev *nfbdev, | |||
250 | info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_COPYAREA | | 250 | info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_COPYAREA | |
251 | FBINFO_HWACCEL_FILLRECT | | 251 | FBINFO_HWACCEL_FILLRECT | |
252 | FBINFO_HWACCEL_IMAGEBLIT; | 252 | FBINFO_HWACCEL_IMAGEBLIT; |
253 | info->flags |= FBINFO_CAN_FORCE_OUTPUT; | ||
253 | info->fbops = &nouveau_fbcon_ops; | 254 | info->fbops = &nouveau_fbcon_ops; |
254 | info->fix.smem_start = dev->mode_config.fb_base + nvbo->bo.offset - | 255 | info->fix.smem_start = dev->mode_config.fb_base + nvbo->bo.offset - |
255 | dev_priv->vm_vram_base; | 256 | dev_priv->vm_vram_base; |
diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c index dc1634bb0c11..dbf86962bdd1 100644 --- a/drivers/gpu/drm/radeon/radeon_fb.c +++ b/drivers/gpu/drm/radeon/radeon_fb.c | |||
@@ -224,7 +224,7 @@ static int radeonfb_create(struct radeon_fbdev *rfbdev, | |||
224 | 224 | ||
225 | drm_fb_helper_fill_fix(info, fb->pitch, fb->depth); | 225 | drm_fb_helper_fill_fix(info, fb->pitch, fb->depth); |
226 | 226 | ||
227 | info->flags = FBINFO_DEFAULT; | 227 | info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT; |
228 | info->fbops = &radeonfb_ops; | 228 | info->fbops = &radeonfb_ops; |
229 | 229 | ||
230 | tmp = radeon_bo_gpu_offset(rbo) - rdev->mc.vram_start; | 230 | tmp = radeon_bo_gpu_offset(rbo) - rdev->mc.vram_start; |
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index 3b3f5749af92..26bf7cbfecc2 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c | |||
@@ -283,7 +283,8 @@ static inline int fbcon_is_inactive(struct vc_data *vc, struct fb_info *info) | |||
283 | struct fbcon_ops *ops = info->fbcon_par; | 283 | struct fbcon_ops *ops = info->fbcon_par; |
284 | 284 | ||
285 | return (info->state != FBINFO_STATE_RUNNING || | 285 | return (info->state != FBINFO_STATE_RUNNING || |
286 | vc->vc_mode != KD_TEXT || ops->graphics); | 286 | vc->vc_mode != KD_TEXT || ops->graphics) && |
287 | !vt_force_oops_output(vc); | ||
287 | } | 288 | } |
288 | 289 | ||
289 | static inline int get_color(struct vc_data *vc, struct fb_info *info, | 290 | static inline int get_color(struct vc_data *vc, struct fb_info *info, |
@@ -1073,6 +1074,7 @@ static void fbcon_init(struct vc_data *vc, int init) | |||
1073 | if (p->userfont) | 1074 | if (p->userfont) |
1074 | charcnt = FNTCHARCNT(p->fontdata); | 1075 | charcnt = FNTCHARCNT(p->fontdata); |
1075 | 1076 | ||
1077 | vc->vc_panic_force_write = !!(info->flags & FBINFO_CAN_FORCE_OUTPUT); | ||
1076 | vc->vc_can_do_color = (fb_get_color_depth(&info->var, &info->fix)!=1); | 1078 | vc->vc_can_do_color = (fb_get_color_depth(&info->var, &info->fix)!=1); |
1077 | vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800; | 1079 | vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800; |
1078 | if (charcnt == 256) { | 1080 | if (charcnt == 256) { |
diff --git a/include/linux/console_struct.h b/include/linux/console_struct.h index 38fe59dc89ae..d7d9acdccffb 100644 --- a/include/linux/console_struct.h +++ b/include/linux/console_struct.h | |||
@@ -105,6 +105,7 @@ struct vc_data { | |||
105 | struct vc_data **vc_display_fg; /* [!] Ptr to var holding fg console for this display */ | 105 | struct vc_data **vc_display_fg; /* [!] Ptr to var holding fg console for this display */ |
106 | unsigned long vc_uni_pagedir; | 106 | unsigned long vc_uni_pagedir; |
107 | unsigned long *vc_uni_pagedir_loc; /* [!] Location of uni_pagedir variable for this console */ | 107 | unsigned long *vc_uni_pagedir_loc; /* [!] Location of uni_pagedir variable for this console */ |
108 | bool vc_panic_force_write; /* when oops/panic this VC can accept forced output/blanking */ | ||
108 | /* additional information is in vt_kern.h */ | 109 | /* additional information is in vt_kern.h */ |
109 | }; | 110 | }; |
110 | 111 | ||
diff --git a/include/linux/fb.h b/include/linux/fb.h index 0c5659c41b01..f0268deca658 100644 --- a/include/linux/fb.h +++ b/include/linux/fb.h | |||
@@ -825,6 +825,10 @@ struct fb_tile_ops { | |||
825 | */ | 825 | */ |
826 | #define FBINFO_BE_MATH 0x100000 | 826 | #define FBINFO_BE_MATH 0x100000 |
827 | 827 | ||
828 | /* report to the VT layer that this fb driver can accept forced console | ||
829 | output like oopses */ | ||
830 | #define FBINFO_CAN_FORCE_OUTPUT 0x200000 | ||
831 | |||
828 | struct fb_info { | 832 | struct fb_info { |
829 | int node; | 833 | int node; |
830 | int flags; | 834 | int flags; |
diff --git a/include/linux/vt_kern.h b/include/linux/vt_kern.h index 7f56db4a79f0..56cce345aa8d 100644 --- a/include/linux/vt_kern.h +++ b/include/linux/vt_kern.h | |||
@@ -100,6 +100,13 @@ extern int unbind_con_driver(const struct consw *csw, int first, int last, | |||
100 | int deflt); | 100 | int deflt); |
101 | int vty_init(const struct file_operations *console_fops); | 101 | int vty_init(const struct file_operations *console_fops); |
102 | 102 | ||
103 | static inline bool vt_force_oops_output(struct vc_data *vc) | ||
104 | { | ||
105 | if (oops_in_progress && vc->vc_panic_force_write) | ||
106 | return true; | ||
107 | return false; | ||
108 | } | ||
109 | |||
103 | /* | 110 | /* |
104 | * vc_screen.c shares this temporary buffer with the console write code so that | 111 | * vc_screen.c shares this temporary buffer with the console write code so that |
105 | * we can easily avoid touching user space while holding the console spinlock. | 112 | * we can easily avoid touching user space while holding the console spinlock. |