summaryrefslogtreecommitdiff
path: root/linux-core
diff options
context:
space:
mode:
authorJesse Barnes <jbarnes@jbarnes-t61.(none)>2008-06-18 13:57:39 -0700
committerJesse Barnes <jbarnes@virtuousgeek.org>2008-06-18 13:57:39 -0700
commit7010d500072977f63a0bac08f2141d69dbd19595 (patch)
tree60db58e7d12d0db75b19b730d670eee51ed7f0ee /linux-core
parentc987e76d953b6aecbfb69058fc4c387aa3fb33c9 (diff)
i915: switch back to fbcon on panic
Normally when X is running, panic messages will be invisible and the machine will just appear to hard hang. This patch adds support for switching back to the fbcon framebuffer on panic (through the use of a panic notifier registration) so we can see what happened. Note that in order to be really useful, X will have to run its VT in something other than KD_GRAPHICS mode. Also, not all kernel errors result in panics, some go through BUG() which may trigger another type of event, not resulting in a switch.
Diffstat (limited to 'linux-core')
-rw-r--r--linux-core/intel_fb.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/linux-core/intel_fb.c b/linux-core/intel_fb.c
index 856ec868..64a8fc94 100644
--- a/linux-core/intel_fb.c
+++ b/linux-core/intel_fb.c
@@ -581,6 +581,22 @@ int intelfb_resize(struct drm_device *dev, struct drm_crtc *crtc)
}
EXPORT_SYMBOL(intelfb_resize);
+static struct drm_mode_set panic_mode;
+
+int intelfb_panic(struct notifier_block *n, unsigned long ununsed,
+ void *panic_str)
+{
+ DRM_ERROR("panic occurred, switching back to text console\n");
+ drm_crtc_helper_set_config(&panic_mode);
+
+ return 0;
+}
+EXPORT_SYMBOL(intelfb_panic);
+
+static struct notifier_block paniced = {
+ .notifier_call = intelfb_panic,
+};
+
int intelfb_create(struct drm_device *dev, uint32_t fb_width, uint32_t fb_height,
uint32_t surface_width, uint32_t surface_height,
struct intel_framebuffer **intel_fb_p)
@@ -831,6 +847,12 @@ static int intelfb_multi_fb_probe_crtc(struct drm_device *dev, struct drm_crtc *
printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node,
info->fix.id);
+
+ /* Switch back to kernel console on panic */
+ panic_mode = *modeset;
+ atomic_notifier_chain_register(&panic_notifier_list, &paniced);
+ printk(KERN_INFO "registered panic notifier\n");
+
return 0;
}
@@ -952,6 +974,12 @@ static int intelfb_single_fb_probe(struct drm_device *dev)
printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node,
info->fix.id);
+
+ /* Switch back to kernel console on panic */
+ panic_mode = *modeset;
+ atomic_notifier_chain_register(&panic_notifier_list, &paniced);
+ printk(KERN_INFO "registered panic notifier\n");
+
return 0;
}
@@ -1005,6 +1033,9 @@ int intelfb_remove(struct drm_device *dev, struct drm_framebuffer *fb)
drm_bo_usage_deref_unlocked(&intel_fb->bo);
framebuffer_release(info);
}
+
+ atomic_notifier_chain_unregister(&panic_notifier_list, &paniced);
+ memset(&panic_mode, 0, sizeof(struct drm_mode_set));
return 0;
}
EXPORT_SYMBOL(intelfb_remove);