summary refs log tree commit diff
path: root/drivers/serial
diff options
context:
space:
mode:
authorJason Wessel <jason.wessel@windriver.com>2010-08-05 09:22:30 -0500
committerJason Wessel <jason.wessel@windriver.com>2010-08-05 09:22:30 -0500
commit408a4be1f8cbee511895ee07da2a007a5a24303f (patch)
tree9d31d812ffe9eaec638f0698b3e6ba913ca51a7e /drivers/serial
parent81d4450732c68aa728f2c86c0c2993c6cfc3d032 (diff)
downloadlinux-408a4be1f8cbee511895ee07da2a007a5a24303f.tar.gz
kgdboc: Add call backs to allow kernel mode switching
Add the kms keyword processing to kgdboc and the callbacks to invoke
console switching when ever kgdboc is started with "kgdboc=kms,kbd".

Signed-off-by: Jason Wessel <jason.wessel@windriver.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Diffstat (limited to 'drivers/serial')
-rw-r--r--drivers/serial/kgdboc.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/drivers/serial/kgdboc.c b/drivers/serial/kgdboc.c
index a9a94ae72349..39f9a1adaa75 100644
--- a/drivers/serial/kgdboc.c
+++ b/drivers/serial/kgdboc.c
@@ -17,6 +17,7 @@
 #include <linux/kdb.h>
 #include <linux/tty.h>
 #include <linux/console.h>
+#include <linux/vt_kern.h>
 
 #define MAX_CONFIG_LEN		40
 
@@ -31,6 +32,7 @@ static struct kparam_string kps = {
 	.maxlen			= MAX_CONFIG_LEN,
 };
 
+static int kgdboc_use_kms;  /* 1 if we use kernel mode switching */
 static struct tty_driver	*kgdb_tty_driver;
 static int			kgdb_tty_line;
 
@@ -104,6 +106,12 @@ static int configure_kgdboc(void)
 	kgdboc_io_ops.is_console = 0;
 	kgdb_tty_driver = NULL;
 
+	kgdboc_use_kms = 0;
+	if (strncmp(cptr, "kms,", 4) == 0) {
+		cptr += 4;
+		kgdboc_use_kms = 1;
+	}
+
 	if (kgdboc_register_kbd(&cptr))
 		goto do_register;
 
@@ -201,8 +209,14 @@ static int param_set_kgdboc_var(const char *kmessage, struct kernel_param *kp)
 	return configure_kgdboc();
 }
 
+static int dbg_restore_graphics;
+
 static void kgdboc_pre_exp_handler(void)
 {
+	if (!dbg_restore_graphics && kgdboc_use_kms) {
+		dbg_restore_graphics = 1;
+		con_debug_enter(vc_cons[fg_console].d);
+	}
 	/* Increment the module count when the debugger is active */
 	if (!kgdb_connected)
 		try_module_get(THIS_MODULE);
@@ -213,6 +227,10 @@ static void kgdboc_post_exp_handler(void)
 	/* decrement the module count when the debugger detaches */
 	if (!kgdb_connected)
 		module_put(THIS_MODULE);
+	if (kgdboc_use_kms && dbg_restore_graphics) {
+		dbg_restore_graphics = 0;
+		con_debug_leave();
+	}
 }
 
 static struct kgdb_io kgdboc_io_ops = {