From patchwork Thu Oct 7 20:35:46 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Wessel X-Patchwork-Id: 238911 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id o97Katdb012785 for ; Thu, 7 Oct 2010 20:36:55 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755627Ab0JGUgK (ORCPT ); Thu, 7 Oct 2010 16:36:10 -0400 Received: from mail.windriver.com ([147.11.1.11]:57526 "EHLO mail.windriver.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753883Ab0JGUgG (ORCPT ); Thu, 7 Oct 2010 16:36:06 -0400 Received: from ALA-MAIL03.corp.ad.wrs.com (ala-mail03 [147.11.57.144]) by mail.windriver.com (8.14.3/8.14.3) with ESMTP id o97KZqYs016047; Thu, 7 Oct 2010 13:35:52 -0700 (PDT) Received: from ala-mail06.corp.ad.wrs.com ([147.11.57.147]) by ALA-MAIL03.corp.ad.wrs.com with Microsoft SMTPSVC(6.0.3790.1830); Thu, 7 Oct 2010 13:35:52 -0700 Received: from localhost.localdomain ([172.25.32.37]) by ala-mail06.corp.ad.wrs.com with Microsoft SMTPSVC(6.0.3790.1830); Thu, 7 Oct 2010 13:35:52 -0700 From: Jason Wessel To: dmitry.torokhov@gmail.com Cc: kgdb-bugreport@lists.sourceforge.net, linux-input@vger.kernel.org, linux-kernel@vger.kernel.org, Jason Wessel , Greg Kroah-Hartman Subject: [PATCH 1/3] keyboard,kgdboc: Allow key release on kernel resume Date: Thu, 7 Oct 2010 15:35:46 -0500 Message-Id: <1286483748-1171-2-git-send-email-jason.wessel@windriver.com> X-Mailer: git-send-email 1.6.4.rc1 In-Reply-To: <1286483748-1171-1-git-send-email-jason.wessel@windriver.com> References: <1286483748-1171-1-git-send-email-jason.wessel@windriver.com> X-OriginalArrivalTime: 07 Oct 2010 20:35:52.0111 (UTC) FILETIME=[3BC873F0:01CB665F] Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter1.kernel.org [140.211.167.41]); Thu, 07 Oct 2010 20:36:55 +0000 (UTC) diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c index a7ca752..0c6c641 100644 --- a/drivers/char/keyboard.c +++ b/drivers/char/keyboard.c @@ -363,6 +363,43 @@ static void to_utf8(struct vc_data *vc, uint c) } } +#ifdef CONFIG_KDB_KEYBOARD +static int kbd_clear_keys_helper(struct input_handle *handle, void *data) +{ + unsigned int *keycode = data; + input_inject_event(handle, EV_KEY, *keycode, 0); + return 0; +} + +static void kbd_clear_keys_callback(struct work_struct *dummy) +{ + unsigned int i, j, k; + + for (i = 0; i < ARRAY_SIZE(key_down); i++) { + if (!key_down[i]) + continue; + + k = i * BITS_PER_LONG; + + for (j = 0; j < BITS_PER_LONG; j++, k++) { + if (!test_bit(k, key_down)) + continue; + input_handler_for_each_handle(&kbd_handler, &k, + kbd_clear_keys_helper); + } + } +} + +static DECLARE_WORK(kbd_clear_keys_work, kbd_clear_keys_callback); + +/* Called to clear any key presses after resuming the kernel. */ +void kbd_dbg_clear_keys(void) +{ + schedule_work(&kbd_clear_keys_work); +} +EXPORT_SYMBOL_GPL(kbd_dbg_clear_keys); +#endif /* CONFIG_KDB_KEYBOARD */ + /* * Called after returning from RAW mode or when changing consoles - recompute * shift_down[] and shift_state from key_down[] maybe called when keymap is diff --git a/drivers/serial/kgdboc.c b/drivers/serial/kgdboc.c index 39f9a1a..62b6edc 100644 --- a/drivers/serial/kgdboc.c +++ b/drivers/serial/kgdboc.c @@ -18,6 +18,7 @@ #include #include #include +#include #define MAX_CONFIG_LEN 40 @@ -37,12 +38,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 @@ -65,9 +70,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) @@ -231,6 +243,7 @@ static void kgdboc_post_exp_handler(void) dbg_restore_graphics = 0; con_debug_leave(); } + kgdboc_clear_kbd(); } static struct kgdb_io kgdboc_io_ops = { diff --git a/include/linux/kbd_kern.h b/include/linux/kbd_kern.h index 506ad20..ae87c0a 100644 --- a/include/linux/kbd_kern.h +++ b/include/linux/kbd_kern.h @@ -144,6 +144,7 @@ struct console; int getkeycode(unsigned int scancode); int setkeycode(unsigned int scancode, unsigned int keycode); void compute_shiftstate(void); +void kbd_dbg_clear_keys(void); /* defkeymap.c */