Input: add support for autorepeat maximum count

Add REP_MAX_COUNT to input device, so that it doesn't repeat a key
press forever. This protects from the case where GFRM100 sends
a key-down event but never sends a key-up event due to Bluetooth link
going down or some other device error.

The autorepeat parameters of an input device can be read and modified
by using ioctl() on the input event device, e.g. /dev/input/event0.

The parameters can also be set directly from the driver that creates
the input device by calling input_enable_softrepeat().

This change evolved from Bruno 2.6.37 kernel commits:

commit e2a0d4d2b11c04c232ece9f9a5b82fc6b9d75b08
Author: Petri Gynther <pgynther@google.com>
Date:   Thu Apr 17 17:18:27 2014 -0700
Limit GFRM100 keypress auto-repeat to REP_MAX_COUNT=300

commit bf8c0864d08b80339204401f252efbe2037d6852
Author: Petri Gynther <pgynther@google.com>
Date:   Fri Apr 18 17:01:27 2014 -0700
Fix commit "Limit GFRM100 keypress auto-repeat"

Change-Id: I9688b92ae400e376654407a220e8a29b9d0fda69
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index ce953d8..f260bd4 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -847,24 +847,34 @@
 		return 0;
 
 	case EVIOCGREP:
+	case EVIOCGREP_V2:
 		if (!test_bit(EV_REP, dev->evbit))
 			return -ENOSYS;
 		if (put_user(dev->rep[REP_DELAY], ip))
 			return -EFAULT;
 		if (put_user(dev->rep[REP_PERIOD], ip + 1))
 			return -EFAULT;
+		if (cmd == EVIOCGREP_V2 &&
+		    put_user(dev->rep[REP_MAX_COUNT], ip + 2))
+			return -EFAULT;
 		return 0;
 
 	case EVIOCSREP:
+	case EVIOCSREP_V2:
 		if (!test_bit(EV_REP, dev->evbit))
 			return -ENOSYS;
 		if (get_user(u, ip))
 			return -EFAULT;
 		if (get_user(v, ip + 1))
 			return -EFAULT;
+		if (cmd == EVIOCSREP_V2 && get_user(t, ip + 2))
+			return -EFAULT;
 
 		input_inject_event(&evdev->handle, EV_REP, REP_DELAY, u);
 		input_inject_event(&evdev->handle, EV_REP, REP_PERIOD, v);
+		if (cmd == EVIOCSREP_V2)
+			input_inject_event(&evdev->handle, EV_REP,
+					   REP_MAX_COUNT, t);
 
 		return 0;
 
diff --git a/drivers/input/input.c b/drivers/input/input.c
index 8790991..4289286 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -78,6 +78,7 @@
 	    dev->rep[REP_PERIOD] && dev->rep[REP_DELAY] &&
 	    dev->timer.data) {
 		dev->repeat_key = code;
+		dev->repeat_count = 0;
 		mod_timer(&dev->timer,
 			  jiffies + msecs_to_jiffies(dev->rep[REP_DELAY]));
 	}
@@ -191,7 +192,9 @@
 
 		input_pass_values(dev, vals, ARRAY_SIZE(vals));
 
-		if (dev->rep[REP_PERIOD])
+		if (dev->rep[REP_PERIOD] &&
+		    (dev->rep[REP_MAX_COUNT] == 0 ||
+		     ++dev->repeat_count < dev->rep[REP_MAX_COUNT]))
 			mod_timer(&dev->timer, jiffies +
 					msecs_to_jiffies(dev->rep[REP_PERIOD]));
 	}
@@ -1642,6 +1645,7 @@
 	if (activate && test_bit(EV_REP, dev->evbit)) {
 		dev->event(dev, EV_REP, REP_PERIOD, dev->rep[REP_PERIOD]);
 		dev->event(dev, EV_REP, REP_DELAY, dev->rep[REP_DELAY]);
+		dev->event(dev, EV_REP, REP_MAX_COUNT, dev->rep[REP_MAX_COUNT]);
 	}
 }
 
@@ -2048,15 +2052,18 @@
  * @dev: input device
  * @delay: repeat delay
  * @period: repeat period
+ * @max_count: repeat maximum count
  *
  * Enable software autorepeat on the input device.
  */
-void input_enable_softrepeat(struct input_dev *dev, int delay, int period)
+void input_enable_softrepeat(struct input_dev *dev, int delay, int period,
+			     int max_count)
 {
 	dev->timer.data = (unsigned long) dev;
 	dev->timer.function = input_repeat_key;
 	dev->rep[REP_DELAY] = delay;
 	dev->rep[REP_PERIOD] = period;
+	dev->rep[REP_MAX_COUNT] = max_count;
 }
 EXPORT_SYMBOL(input_enable_softrepeat);
 
@@ -2125,7 +2132,7 @@
 	 * is handled by the driver itself and we don't do it in input.c.
 	 */
 	if (!dev->rep[REP_DELAY] && !dev->rep[REP_PERIOD])
-		input_enable_softrepeat(dev, 250, 33);
+		input_enable_softrepeat(dev, 250, 33, 0);
 
 	if (!dev->getkeycode)
 		dev->getkeycode = input_default_getkeycode;
diff --git a/include/linux/input.h b/include/linux/input.h
index 1e96769..dba6d07 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -151,6 +151,7 @@
 	struct ff_device *ff;
 
 	unsigned int repeat_key;
+	unsigned int repeat_count;
 	struct timer_list timer;
 
 	int rep[REP_CNT];
@@ -469,7 +470,8 @@
 int input_set_keycode(struct input_dev *dev,
 		      const struct input_keymap_entry *ke);
 
-void input_enable_softrepeat(struct input_dev *dev, int delay, int period);
+void input_enable_softrepeat(struct input_dev *dev, int delay, int period,
+			     int max_count);
 
 extern struct class input_class;
 
diff --git a/include/uapi/linux/input.h b/include/uapi/linux/input.h
index f484952..3582ea9 100644
--- a/include/uapi/linux/input.h
+++ b/include/uapi/linux/input.h
@@ -100,7 +100,9 @@
 #define EVIOCGVERSION		_IOR('E', 0x01, int)			/* get driver version */
 #define EVIOCGID		_IOR('E', 0x02, struct input_id)	/* get device ID */
 #define EVIOCGREP		_IOR('E', 0x03, unsigned int[2])	/* get repeat settings */
+#define EVIOCGREP_V2		_IOR('E', 0x03, unsigned int[3])
 #define EVIOCSREP		_IOW('E', 0x03, unsigned int[2])	/* set repeat settings */
+#define EVIOCSREP_V2		_IOW('E', 0x03, unsigned int[3])
 
 #define EVIOCGKEYCODE		_IOR('E', 0x04, unsigned int[2])        /* get keycode */
 #define EVIOCGKEYCODE_V2	_IOR('E', 0x04, struct input_keymap_entry)
@@ -901,7 +903,8 @@
 
 #define REP_DELAY		0x00
 #define REP_PERIOD		0x01
-#define REP_MAX			0x01
+#define REP_MAX_COUNT		0x02
+#define REP_MAX			0x02
 #define REP_CNT			(REP_MAX+1)
 
 /*