summaryrefslogtreecommitdiff
path: root/drivers/serial
diff options
context:
space:
mode:
authorJason Wessel <jason.wessel@windriver.com>2010-03-03 15:35:55 -0600
committerJason Wessel <jason.wessel@windriver.com>2010-03-03 15:35:55 -0600
commit8b1f8e0baba1e8b49621e8cf39256bb56b0d6e06 (patch)
tree9a43744f2aec5bd2a331eb093321aefb95c487fa /drivers/serial
parent6bddd57aeac186f65f2be6a5317adc83571745ff (diff)
keyboard,kgdboc: Allow key release on kernel resume
When using a keyboard with kdb, a hook point to free all the keystrokes is required for resuming kernel operations. This is mainly because there is no way to force the end user to hold down the original keys that were pressed prior to entering kdb when resuming the kernel. The kgdboc driver will call kbd_dbg_clear_keys() just prior to resuming the kernel execution which will schedule a callback to clear any keys which were depressed prior to the entering the kernel debugger. CC: Dmitry Torokhov <dmitry.torokhov@gmail.com> CC: Greg Kroah-Hartman <gregkh@suse.de> CC: linux-input@vger.kernel.org Signed-off-by: Jason Wessel <jason.wessel@windriver.com>
Diffstat (limited to 'drivers/serial')
-rw-r--r--drivers/serial/kgdboc.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/drivers/serial/kgdboc.c b/drivers/serial/kgdboc.c
index a9a94ae72349..5af32b48d499 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/kbd_kern.h>
#define MAX_CONFIG_LEN 40
@@ -35,12 +36,16 @@ static struct tty_driver *kgdb_tty_driver;
static int kgdb_tty_line;
#ifdef CONFIG_KDB_KEYBOARD
+static bool kgdboc_use_kbd;
+
static int kgdboc_register_kbd(char **cptr)
{
+ kgdboc_use_kbd = false;
if (strncmp(*cptr, "kbd", 3) == 0) {
if (kdb_poll_idx < KDB_POLL_FUNC_MAX) {
kdb_poll_funcs[kdb_poll_idx] = kdb_get_kbd_char;
kdb_poll_idx++;
+ kgdboc_use_kbd = true;
if (cptr[0][3] == ',')
*cptr += 4;
else
@@ -63,9 +68,16 @@ static void kgdboc_unregister_kbd(void)
}
}
}
+
+static inline void kgdboc_clear_kbd(void)
+{
+ if (kgdboc_use_kbd)
+ kbd_dbg_clear_keys(); /* Release all pressed keys */
+}
#else /* ! CONFIG_KDB_KEYBOARD */
#define kgdboc_register_kbd(x) 0
#define kgdboc_unregister_kbd()
+#define kgdboc_clear_kbd()
#endif /* ! CONFIG_KDB_KEYBOARD */
static int kgdboc_option_setup(char *opt)
@@ -213,6 +225,7 @@ static void kgdboc_post_exp_handler(void)
/* decrement the module count when the debugger detaches */
if (!kgdb_connected)
module_put(THIS_MODULE);
+ kgdboc_clear_kbd();
}
static struct kgdb_io kgdboc_io_ops = {