aboutsummaryrefslogtreecommitdiff
path: root/drivers/input
diff options
context:
space:
mode:
authorHenrik Rydberg2012-08-10 21:39:38 +0200
committerHenrik Rydberg2012-09-19 19:50:17 +0200
commit0672120a2ee7c533dfec6db7c3e43450f439e5ff (patch)
tree5391ff51230e52c22ed4d5d8c1a6026cf87b1206 /drivers/input
parent7c75bf99271139ca7cb2d0cca3be11f1f7c59efd (diff)
Input: Make sure we follow all EV_KEY events
For some EV_KEY types, sending a larger-than-one value causes the input state to oscillate. This patch makes sure this cannot happen, clearing up the autorepeat bypass logic in the process. Tested-by: Benjamin Tissoires <benjamin.tissoires@enac.fr> Tested-by: Ping Cheng <pingc@wacom.com> Acked-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> Signed-off-by: Henrik Rydberg <rydberg@euromail.se>
Diffstat (limited to 'drivers/input')
-rw-r--r--drivers/input/input.c20
1 files changed, 13 insertions, 7 deletions
diff --git a/drivers/input/input.c b/drivers/input/input.c
index fb3a2c112deb..f075fbbfb1e7 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -240,24 +240,30 @@ static void input_handle_event(struct input_dev *dev,
break;
case EV_KEY:
- if (is_event_supported(code, dev->keybit, KEY_MAX) &&
- !!test_bit(code, dev->key) != value) {
+ if (is_event_supported(code, dev->keybit, KEY_MAX)) {
+
+ /* auto-repeat bypasses state updates */
+ if (value == 2) {
+ disposition = INPUT_PASS_TO_HANDLERS;
+ break;
+ }
+
+ if (!!test_bit(code, dev->key) != !!value) {
- if (value != 2) {
__change_bit(code, dev->key);
+ disposition = INPUT_PASS_TO_HANDLERS;
+
if (value)
input_start_autorepeat(dev, code);
else
input_stop_autorepeat(dev);
}
-
- disposition = INPUT_PASS_TO_HANDLERS;
}
break;
case EV_SW:
if (is_event_supported(code, dev->swbit, SW_MAX) &&
- !!test_bit(code, dev->sw) != value) {
+ !!test_bit(code, dev->sw) != !!value) {
__change_bit(code, dev->sw);
disposition = INPUT_PASS_TO_HANDLERS;
@@ -284,7 +290,7 @@ static void input_handle_event(struct input_dev *dev,
case EV_LED:
if (is_event_supported(code, dev->ledbit, LED_MAX) &&
- !!test_bit(code, dev->led) != value) {
+ !!test_bit(code, dev->led) != !!value) {
__change_bit(code, dev->led);
disposition = INPUT_PASS_TO_ALL;