diff options
| author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2010-11-03 14:04:05 -0400 |
|---|---|---|
| committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2010-11-03 14:04:52 -0400 |
| commit | 111c182340cd22e238ab1cc6564df336c6ebd7cb (patch) | |
| tree | b8586938bfd7e4993ec4e505fa17f02aefe0abc7 | |
| parent | b50b521694cb7093640879d3279b88d2873f6183 (diff) | |
kgdboc: reset input devices (keyboards) when exiting debugger
Use the newly exported input_reset_device() call to reset LED state and
mark all keys/buttons as released on all keyboard-like devices when
exiting the debugger.
[jason.wessel@windriver.com: fix compile without keyboard input driver]
Signed-off-by: Jason Wessel <jason.wessel@windriver.com>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
| -rw-r--r-- | drivers/serial/kgdboc.c | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/drivers/serial/kgdboc.c b/drivers/serial/kgdboc.c index d4b711c9a416..3374618300af 100644 --- a/drivers/serial/kgdboc.c +++ b/drivers/serial/kgdboc.c | |||
| @@ -18,6 +18,7 @@ | |||
| 18 | #include <linux/tty.h> | 18 | #include <linux/tty.h> |
| 19 | #include <linux/console.h> | 19 | #include <linux/console.h> |
| 20 | #include <linux/vt_kern.h> | 20 | #include <linux/vt_kern.h> |
| 21 | #include <linux/input.h> | ||
| 21 | 22 | ||
| 22 | #define MAX_CONFIG_LEN 40 | 23 | #define MAX_CONFIG_LEN 40 |
| 23 | 24 | ||
| @@ -37,6 +38,61 @@ static struct tty_driver *kgdb_tty_driver; | |||
| 37 | static int kgdb_tty_line; | 38 | static int kgdb_tty_line; |
| 38 | 39 | ||
| 39 | #ifdef CONFIG_KDB_KEYBOARD | 40 | #ifdef CONFIG_KDB_KEYBOARD |
| 41 | static int kgdboc_reset_connect(struct input_handler *handler, | ||
| 42 | struct input_dev *dev, | ||
| 43 | const struct input_device_id *id) | ||
| 44 | { | ||
| 45 | input_reset_device(dev); | ||
| 46 | |||
| 47 | /* Retrun an error - we do not want to bind, just to reset */ | ||
| 48 | return -ENODEV; | ||
| 49 | } | ||
| 50 | |||
| 51 | static void kgdboc_reset_disconnect(struct input_handle *handle) | ||
| 52 | { | ||
| 53 | /* We do not expect anyone to actually bind to us */ | ||
| 54 | BUG(); | ||
| 55 | } | ||
| 56 | |||
| 57 | static const struct input_device_id kgdboc_reset_ids[] = { | ||
| 58 | { | ||
| 59 | .flags = INPUT_DEVICE_ID_MATCH_EVBIT, | ||
| 60 | .evbit = { BIT_MASK(EV_KEY) }, | ||
| 61 | }, | ||
| 62 | { } | ||
| 63 | }; | ||
| 64 | |||
| 65 | static struct input_handler kgdboc_reset_handler = { | ||
| 66 | .connect = kgdboc_reset_connect, | ||
| 67 | .disconnect = kgdboc_reset_disconnect, | ||
| 68 | .name = "kgdboc_reset", | ||
| 69 | .id_table = kgdboc_reset_ids, | ||
| 70 | }; | ||
| 71 | |||
| 72 | static DEFINE_MUTEX(kgdboc_reset_mutex); | ||
| 73 | |||
| 74 | static void kgdboc_restore_input_helper(struct work_struct *dummy) | ||
| 75 | { | ||
| 76 | /* | ||
| 77 | * We need to take a mutex to prevent several instances of | ||
| 78 | * this work running on different CPUs so they don't try | ||
| 79 | * to register again already registered handler. | ||
| 80 | */ | ||
| 81 | mutex_lock(&kgdboc_reset_mutex); | ||
| 82 | |||
| 83 | if (input_register_handler(&kgdboc_reset_handler) == 0) | ||
| 84 | input_unregister_handler(&kgdboc_reset_handler); | ||
| 85 | |||
| 86 | mutex_unlock(&kgdboc_reset_mutex); | ||
| 87 | } | ||
| 88 | |||
| 89 | static DECLARE_WORK(kgdboc_restore_input_work, kgdboc_restore_input_helper); | ||
| 90 | |||
| 91 | static void kgdboc_restore_input(void) | ||
| 92 | { | ||
| 93 | schedule_work(&kgdboc_restore_input_work); | ||
| 94 | } | ||
| 95 | |||
| 40 | static int kgdboc_register_kbd(char **cptr) | 96 | static int kgdboc_register_kbd(char **cptr) |
| 41 | { | 97 | { |
| 42 | if (strncmp(*cptr, "kbd", 3) == 0) { | 98 | if (strncmp(*cptr, "kbd", 3) == 0) { |
| @@ -64,10 +120,12 @@ static void kgdboc_unregister_kbd(void) | |||
| 64 | i--; | 120 | i--; |
| 65 | } | 121 | } |
| 66 | } | 122 | } |
| 123 | flush_work_sync(&kgdboc_restore_input_work); | ||
| 67 | } | 124 | } |
| 68 | #else /* ! CONFIG_KDB_KEYBOARD */ | 125 | #else /* ! CONFIG_KDB_KEYBOARD */ |
| 69 | #define kgdboc_register_kbd(x) 0 | 126 | #define kgdboc_register_kbd(x) 0 |
| 70 | #define kgdboc_unregister_kbd() | 127 | #define kgdboc_unregister_kbd() |
| 128 | #define kgdboc_restore_input() | ||
| 71 | #endif /* ! CONFIG_KDB_KEYBOARD */ | 129 | #endif /* ! CONFIG_KDB_KEYBOARD */ |
| 72 | 130 | ||
| 73 | static int kgdboc_option_setup(char *opt) | 131 | static int kgdboc_option_setup(char *opt) |
| @@ -231,6 +289,7 @@ static void kgdboc_post_exp_handler(void) | |||
| 231 | dbg_restore_graphics = 0; | 289 | dbg_restore_graphics = 0; |
| 232 | con_debug_leave(); | 290 | con_debug_leave(); |
| 233 | } | 291 | } |
| 292 | kgdboc_restore_input(); | ||
| 234 | } | 293 | } |
| 235 | 294 | ||
| 236 | static struct kgdb_io kgdboc_io_ops = { | 295 | static struct kgdb_io kgdboc_io_ops = { |
