--- v1
+++ v2
@@ -1,88 +1,61 @@
-Preparing to split event filtering and event passing, move the
-autorepeat function to the point where the event is actually passed.
+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.
Signed-off-by: Henrik Rydberg <rydberg@euromail.se>
---
- drivers/input/input.c | 46 +++++++++++++++++++++++++---------------------
- 1 file changed, 25 insertions(+), 21 deletions(-)
+ drivers/input/input.c | 20 +++++++++++++-------
+ 1 file changed, 13 insertions(+), 7 deletions(-)
diff --git a/drivers/input/input.c b/drivers/input/input.c
-index 4d64500..a57c4a5 100644
+index 8ebf116..4d64500 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
-@@ -69,6 +69,22 @@ static int input_defuzz_abs_event(int value, int old_val, int fuzz)
- return value;
- }
+@@ -239,24 +239,30 @@ static void input_handle_event(struct input_dev *dev,
+ break;
-+static void input_start_autorepeat(struct input_dev *dev, int code)
-+{
-+ if (test_bit(EV_REP, dev->evbit) &&
-+ dev->rep[REP_PERIOD] && dev->rep[REP_DELAY] &&
-+ dev->timer.data) {
-+ dev->repeat_key = code;
-+ mod_timer(&dev->timer,
-+ jiffies + msecs_to_jiffies(dev->rep[REP_DELAY]));
-+ }
-+}
+ 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)) {
+
-+static void input_stop_autorepeat(struct input_dev *dev)
-+{
-+ del_timer(&dev->timer);
-+}
++ /* auto-repeat bypasses state updates */
++ if (value == 2) {
++ disposition = INPUT_PASS_TO_HANDLERS;
++ break;
++ }
+
- /*
- * Pass event first through all filters and then, if event has not been
- * filtered out, through all open handles. This function is called with
-@@ -105,6 +121,15 @@ static void input_pass_event(struct input_dev *dev,
- }
++ if (!!test_bit(code, dev->key) != !!value) {
- rcu_read_unlock();
+- if (value != 2) {
+ __change_bit(code, dev->key);
++ disposition = INPUT_PASS_TO_HANDLERS;
+
-+ /* trigger auto repeat for key events */
-+ if (type == EV_KEY && value != 2) {
-+ if (value)
-+ input_start_autorepeat(dev, code);
-+ else
-+ input_stop_autorepeat(dev);
-+ }
-+
- }
-
- /*
-@@ -142,22 +167,6 @@ static void input_repeat_key(unsigned long data)
- spin_unlock_irqrestore(&dev->event_lock, flags);
- }
-
--static void input_start_autorepeat(struct input_dev *dev, int code)
--{
-- if (test_bit(EV_REP, dev->evbit) &&
-- dev->rep[REP_PERIOD] && dev->rep[REP_DELAY] &&
-- dev->timer.data) {
-- dev->repeat_key = code;
-- mod_timer(&dev->timer,
-- jiffies + msecs_to_jiffies(dev->rep[REP_DELAY]));
-- }
--}
+ if (value)
+ input_start_autorepeat(dev, code);
+ else
+ input_stop_autorepeat(dev);
+ }
-
--static void input_stop_autorepeat(struct input_dev *dev)
--{
-- del_timer(&dev->timer);
--}
--
- #define INPUT_IGNORE_EVENT 0
- #define INPUT_PASS_TO_HANDLERS 1
- #define INPUT_PASS_TO_DEVICE 2
-@@ -251,11 +260,6 @@ static void input_handle_event(struct input_dev *dev,
-
- __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;
+@@ -283,7 +289,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;
--
-1.7.11.4
+1.7.12