Merge branch 'x86-cpu-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[cascardo/linux.git] / drivers / input / input.c
index 9c79bd5..e1243b4 100644 (file)
@@ -33,25 +33,6 @@ MODULE_LICENSE("GPL");
 
 #define INPUT_DEVICES  256
 
-/*
- * EV_ABS events which should not be cached are listed here.
- */
-static unsigned int input_abs_bypass_init_data[] __initdata = {
-       ABS_MT_TOUCH_MAJOR,
-       ABS_MT_TOUCH_MINOR,
-       ABS_MT_WIDTH_MAJOR,
-       ABS_MT_WIDTH_MINOR,
-       ABS_MT_ORIENTATION,
-       ABS_MT_POSITION_X,
-       ABS_MT_POSITION_Y,
-       ABS_MT_TOOL_TYPE,
-       ABS_MT_BLOB_ID,
-       ABS_MT_TRACKING_ID,
-       ABS_MT_PRESSURE,
-       0
-};
-static unsigned long input_abs_bypass[BITS_TO_LONGS(ABS_CNT)];
-
 static LIST_HEAD(input_dev_list);
 static LIST_HEAD(input_handler_list);
 
@@ -181,6 +162,56 @@ static void input_stop_autorepeat(struct input_dev *dev)
 #define INPUT_PASS_TO_DEVICE   2
 #define INPUT_PASS_TO_ALL      (INPUT_PASS_TO_HANDLERS | INPUT_PASS_TO_DEVICE)
 
+static int input_handle_abs_event(struct input_dev *dev,
+                                 unsigned int code, int *pval)
+{
+       bool is_mt_event;
+       int *pold;
+
+       if (code == ABS_MT_SLOT) {
+               /*
+                * "Stage" the event; we'll flush it later, when we
+                * get actiual touch data.
+                */
+               if (*pval >= 0 && *pval < dev->mtsize)
+                       dev->slot = *pval;
+
+               return INPUT_IGNORE_EVENT;
+       }
+
+       is_mt_event = code >= ABS_MT_FIRST && code <= ABS_MT_LAST;
+
+       if (!is_mt_event) {
+               pold = &dev->abs[code];
+       } else if (dev->mt) {
+               struct input_mt_slot *mtslot = &dev->mt[dev->slot];
+               pold = &mtslot->abs[code - ABS_MT_FIRST];
+       } else {
+               /*
+                * Bypass filtering for multitouch events when
+                * not employing slots.
+                */
+               pold = NULL;
+       }
+
+       if (pold) {
+               *pval = input_defuzz_abs_event(*pval, *pold,
+                                               dev->absfuzz[code]);
+               if (*pold == *pval)
+                       return INPUT_IGNORE_EVENT;
+
+               *pold = *pval;
+       }
+
+       /* Flush pending "slot" event */
+       if (is_mt_event && dev->slot != dev->abs[ABS_MT_SLOT]) {
+               dev->abs[ABS_MT_SLOT] = dev->slot;
+               input_pass_event(dev, EV_ABS, ABS_MT_SLOT, dev->slot);
+       }
+
+       return INPUT_PASS_TO_HANDLERS;
+}
+
 static void input_handle_event(struct input_dev *dev,
                               unsigned int type, unsigned int code, int value)
 {
@@ -196,12 +227,12 @@ static void input_handle_event(struct input_dev *dev,
 
                case SYN_REPORT:
                        if (!dev->sync) {
-                               dev->sync = 1;
+                               dev->sync = true;
                                disposition = INPUT_PASS_TO_HANDLERS;
                        }
                        break;
                case SYN_MT_REPORT:
-                       dev->sync = 0;
+                       dev->sync = false;
                        disposition = INPUT_PASS_TO_HANDLERS;
                        break;
                }
@@ -233,21 +264,9 @@ static void input_handle_event(struct input_dev *dev,
                break;
 
        case EV_ABS:
-               if (is_event_supported(code, dev->absbit, ABS_MAX)) {
-
-                       if (test_bit(code, input_abs_bypass)) {
-                               disposition = INPUT_PASS_TO_HANDLERS;
-                               break;
-                       }
+               if (is_event_supported(code, dev->absbit, ABS_MAX))
+                       disposition = input_handle_abs_event(dev, code, &value);
 
-                       value = input_defuzz_abs_event(value,
-                                       dev->abs[code], dev->absfuzz[code]);
-
-                       if (dev->abs[code] != value) {
-                               dev->abs[code] = value;
-                               disposition = INPUT_PASS_TO_HANDLERS;
-                       }
-               }
                break;
 
        case EV_REL:
@@ -298,7 +317,7 @@ static void input_handle_event(struct input_dev *dev,
        }
 
        if (disposition != INPUT_IGNORE_EVENT && type != EV_SYN)
-               dev->sync = 0;
+               dev->sync = false;
 
        if ((disposition & INPUT_PASS_TO_DEVICE) && dev->event)
                dev->event(dev, type, code, value);
@@ -527,13 +546,31 @@ void input_close_device(struct input_handle *handle)
 }
 EXPORT_SYMBOL(input_close_device);
 
+/*
+ * Simulate keyup events for all keys that are marked as pressed.
+ * The function must be called with dev->event_lock held.
+ */
+static void input_dev_release_keys(struct input_dev *dev)
+{
+       int code;
+
+       if (is_event_supported(EV_KEY, dev->evbit, EV_MAX)) {
+               for (code = 0; code <= KEY_MAX; code++) {
+                       if (is_event_supported(code, dev->keybit, KEY_MAX) &&
+                           __test_and_clear_bit(code, dev->key)) {
+                               input_pass_event(dev, EV_KEY, code, 0);
+                       }
+               }
+               input_pass_event(dev, EV_SYN, SYN_REPORT, 1);
+       }
+}
+
 /*
  * Prepare device for unregistering
  */
 static void input_disconnect_device(struct input_dev *dev)
 {
        struct input_handle *handle;
-       int code;
 
        /*
         * Mark device as going away. Note that we take dev->mutex here
@@ -552,15 +589,7 @@ static void input_disconnect_device(struct input_dev *dev)
         * generate events even after we done here but they will not
         * reach any handlers.
         */
-       if (is_event_supported(EV_KEY, dev->evbit, EV_MAX)) {
-               for (code = 0; code <= KEY_MAX; code++) {
-                       if (is_event_supported(code, dev->keybit, KEY_MAX) &&
-                           __test_and_clear_bit(code, dev->key)) {
-                               input_pass_event(dev, EV_KEY, code, 0);
-                       }
-               }
-               input_pass_event(dev, EV_SYN, SYN_REPORT, 1);
-       }
+       input_dev_release_keys(dev);
 
        list_for_each_entry(handle, &dev->h_list, d_node)
                handle->open = 0;
@@ -684,7 +713,7 @@ int input_set_keycode(struct input_dev *dev,
                      unsigned int scancode, unsigned int keycode)
 {
        unsigned long flags;
-       int old_keycode;
+       unsigned int old_keycode;
        int retval;
 
        if (keycode > KEY_MAX)
@@ -1278,6 +1307,7 @@ static void input_dev_release(struct device *device)
        struct input_dev *dev = to_input_dev(device);
 
        input_ff_destroy(dev);
+       input_mt_destroy_slots(dev);
        kfree(dev);
 
        module_put(THIS_MODULE);
@@ -1433,6 +1463,15 @@ static int input_dev_resume(struct device *dev)
 
        mutex_lock(&input_dev->mutex);
        input_dev_reset(input_dev, true);
+
+       /*
+        * Keys that have been pressed at suspend time are unlikely
+        * to be still pressed when we resume.
+        */
+       spin_lock_irq(&input_dev->event_lock);
+       input_dev_release_keys(input_dev);
+       spin_unlock_irq(&input_dev->event_lock);
+
        mutex_unlock(&input_dev->mutex);
 
        return 0;
@@ -1517,6 +1556,45 @@ void input_free_device(struct input_dev *dev)
 }
 EXPORT_SYMBOL(input_free_device);
 
+/**
+ * input_mt_create_slots() - create MT input slots
+ * @dev: input device supporting MT events and finger tracking
+ * @num_slots: number of slots used by the device
+ *
+ * This function allocates all necessary memory for MT slot handling
+ * in the input device, and adds ABS_MT_SLOT to the device capabilities.
+ */
+int input_mt_create_slots(struct input_dev *dev, unsigned int num_slots)
+{
+       if (!num_slots)
+               return 0;
+
+       dev->mt = kcalloc(num_slots, sizeof(struct input_mt_slot), GFP_KERNEL);
+       if (!dev->mt)
+               return -ENOMEM;
+
+       dev->mtsize = num_slots;
+       input_set_abs_params(dev, ABS_MT_SLOT, 0, num_slots - 1, 0, 0);
+
+       return 0;
+}
+EXPORT_SYMBOL(input_mt_create_slots);
+
+/**
+ * input_mt_destroy_slots() - frees the MT slots of the input device
+ * @dev: input device with allocated MT slots
+ *
+ * This function is only needed in error path as the input core will
+ * automatically free the MT slots when the device is destroyed.
+ */
+void input_mt_destroy_slots(struct input_dev *dev)
+{
+       kfree(dev->mt);
+       dev->mt = NULL;
+       dev->mtsize = 0;
+}
+EXPORT_SYMBOL(input_mt_destroy_slots);
+
 /**
  * input_set_capability - mark device as capable of a certain event
  * @dev: device that is capable of emitting or accepting event
@@ -1926,20 +2004,10 @@ static const struct file_operations input_fops = {
        .open = input_open_file,
 };
 
-static void __init input_init_abs_bypass(void)
-{
-       const unsigned int *p;
-
-       for (p = input_abs_bypass_init_data; *p; p++)
-               input_abs_bypass[BIT_WORD(*p)] |= BIT_MASK(*p);
-}
-
 static int __init input_init(void)
 {
        int err;
 
-       input_init_abs_bypass();
-
        err = class_register(&input_class);
        if (err) {
                printk(KERN_ERR "input: unable to register input_dev class\n");