summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRandall Spangler <rspangler@chromium.org>2014-01-29 09:40:22 -0800
committerchrome-internal-fetch <chrome-internal-fetch@google.com>2014-01-29 21:38:01 +0000
commitc4383ca93f5d2aeb0c03e0b7ae623cf2d1b50ab0 (patch)
treedb4116abe15e55133a3bfb16d014b0286cf8f27b
parentcf43a3b7beb13996e0600605c219d05f562de187 (diff)
downloadchrome-ec-test-5394.B.tar.gz
Fix watchdog in keyboard scan if key outside mask pressedtest-5394.B
If a key is pressed which is not in actual_key_mask, this triggers the keyboard scan interrupt. But read_matrix() would use the key mask to decide that no *real* keys were pressed. So it would immediately drop out of scan mode back to interrupt mode. Which would again be triggered. Lather, rinse, repeat, watchdog. The fix is to use the unmasked key matrix to decide whether to stay in scan mode. This way, the keyboard task sleeps between scans, and the watchdog isn't triggered. (Note that the only way you can hit this bug in real life is to have a keyboard attached which can trigger keys not in actual_key_mask. Which is hard to do, unless you've got a new prototype keyboard with extra keys, or you've spilled lemon juice on your Chromebook...) BUG=chrome-os-partner:25333 BRANCH=rambi TEST=Zero out actual_key_mask in keyboard_scan.c. Press a key. Should not trigger a watchdog. Change-Id: I8c2fbc3e06fa12dfae5c06614814af8f04e24a8a Signed-off-by: Randall Spangler <rspangler@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/184323 Reviewed-by: Dave Parker <dparker@chromium.org> Tested-by: Dave Parker <dparker@chromium.org>
-rw-r--r--common/keyboard_scan.c15
1 files changed, 12 insertions, 3 deletions
diff --git a/common/keyboard_scan.c b/common/keyboard_scan.c
index e5627ba22f..8af50de209 100644
--- a/common/keyboard_scan.c
+++ b/common/keyboard_scan.c
@@ -213,18 +213,27 @@ static int read_matrix(uint8_t *state)
/* Read the row state */
r = keyboard_raw_read_rows();
- /* Mask off keys that don't exist on the actual keyboard */
- r &= keyscan_config.actual_key_mask[c];
+
/* Add in simulated keypresses */
r |= simulated_key[c];
+ /*
+ * Keep track of what keys appear to be pressed. Even if they
+ * don't exist in the matrix, they'll keep triggering
+ * interrupts, so we can't leave scanning mode.
+ */
+ pressed |= r;
+
+ /* Mask off keys that don't exist on the actual keyboard */
+ r &= keyscan_config.actual_key_mask[c];
+
#ifdef CONFIG_KEYBOARD_TEST
/* Use simulated keyscan sequence instead if testing active */
r = keyscan_seq_get_scan(c, r);
#endif
+ /* Store the masked state */
state[c] = r;
- pressed |= r;
}
keyboard_raw_drive_column(KEYBOARD_COLUMN_NONE);