Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 15 Apr 2010 18:49:55 +0000 (11:49 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 15 Apr 2010 18:49:55 +0000 (11:49 -0700)
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input:
  Input: wacom - switch mode upon system resume
  Revert "Input: wacom - merge out and in prox events"
  Input: matrix_keypad - allow platform to disable key autorepeat
  Input: ALPS - add signature for HP Pavilion dm3 laptops
  Input: i8042 - spelling fix
  Input: sparse-keymap - implement safer freeing of the keymap
  Input: update the status of the Multitouch X driver project
  Input: clarify the no-finger event in multitouch protocol
  Input: bcm5974 - retract efi-broken suspend_resume
  Input: sparse-keymap - free the right keymap on error

1  2 
drivers/input/input.c
drivers/input/keyboard/matrix_keypad.c
drivers/input/mouse/alps.c
drivers/input/serio/i8042.c
drivers/input/sparse-keymap.c

diff --combined drivers/input/input.c
@@@ -14,7 -14,6 +14,7 @@@
  #include <linux/types.h>
  #include <linux/input.h>
  #include <linux/module.h>
 +#include <linux/slab.h>
  #include <linux/random.h>
  #include <linux/major.h>
  #include <linux/proc_fs.h>
@@@ -660,7 -659,14 +660,14 @@@ static int input_default_setkeycode(str
  int input_get_keycode(struct input_dev *dev,
                      unsigned int scancode, unsigned int *keycode)
  {
-       return dev->getkeycode(dev, scancode, keycode);
+       unsigned long flags;
+       int retval;
+       spin_lock_irqsave(&dev->event_lock, flags);
+       retval = dev->getkeycode(dev, scancode, keycode);
+       spin_unlock_irqrestore(&dev->event_lock, flags);
+       return retval;
  }
  EXPORT_SYMBOL(input_get_keycode);
  
@@@ -22,7 -22,6 +22,7 @@@
  #include <linux/module.h>
  #include <linux/gpio.h>
  #include <linux/input/matrix_keypad.h>
 +#include <linux/slab.h>
  
  struct matrix_keypad {
        const struct matrix_keypad_platform_data *pdata;
@@@ -374,7 -373,9 +374,9 @@@ static int __devinit matrix_keypad_prob
        input_dev->name         = pdev->name;
        input_dev->id.bustype   = BUS_HOST;
        input_dev->dev.parent   = &pdev->dev;
-       input_dev->evbit[0]     = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
+       input_dev->evbit[0]     = BIT_MASK(EV_KEY);
+       if (!pdata->no_autorepeat)
+               input_dev->evbit[0] |= BIT_MASK(EV_REP);
        input_dev->open         = matrix_keypad_start;
        input_dev->close        = matrix_keypad_stop;
  
@@@ -15,7 -15,6 +15,7 @@@
   * the Free Software Foundation.
   */
  
 +#include <linux/slab.h>
  #include <linux/input.h>
  #include <linux/serio.h>
  #include <linux/libps2.h>
@@@ -64,6 -63,7 +64,7 @@@ static const struct alps_model_info alp
        { { 0x62, 0x02, 0x14 }, 0xcf, 0xcf,
                ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED },
        { { 0x73, 0x02, 0x50 }, 0xcf, 0xcf, ALPS_FOUR_BUTTONS },          /* Dell Vostro 1400 */
+       { { 0x73, 0x02, 0x64 }, 0xf8, 0xf8, 0 },                          /* HP Pavilion dm3 */
        { { 0x52, 0x01, 0x14 }, 0xff, 0xff,
                ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED },      /* Toshiba Tecra A11-11L */
  };
@@@ -21,7 -21,6 +21,7 @@@
  #include <linux/rcupdate.h>
  #include <linux/platform_device.h>
  #include <linux/i8042.h>
 +#include <linux/slab.h>
  
  #include <asm/io.h>
  
@@@ -39,7 -38,7 +39,7 @@@ MODULE_PARM_DESC(noaux, "Do not probe o
  
  static bool i8042_nomux;
  module_param_named(nomux, i8042_nomux, bool, 0);
- MODULE_PARM_DESC(nomux, "Do not check whether an active multiplexing conrtoller is present.");
+ MODULE_PARM_DESC(nomux, "Do not check whether an active multiplexing controller is present.");
  
  static bool i8042_unlock;
  module_param_named(unlock, i8042_unlock, bool, 0);
@@@ -431,7 -430,7 +431,7 @@@ static bool i8042_filter(unsigned char 
        }
  
        if (i8042_platform_filter && i8042_platform_filter(data, str, serio)) {
 -              dbg("Filtered out by platfrom filter\n");
 +              dbg("Filtered out by platform filter\n");
                return true;
        }
  
@@@ -15,7 -15,6 +15,7 @@@
  
  #include <linux/input.h>
  #include <linux/input/sparse-keymap.h>
 +#include <linux/slab.h>
  
  MODULE_AUTHOR("Dmitry Torokhov <dtor@mail.ru>");
  MODULE_DESCRIPTION("Generic support for sparse keymaps");
@@@ -68,12 -67,14 +68,14 @@@ static int sparse_keymap_getkeycode(str
                                    unsigned int scancode,
                                    unsigned int *keycode)
  {
-       const struct key_entry *key =
-                       sparse_keymap_entry_from_scancode(dev, scancode);
+       const struct key_entry *key;
  
-       if (key && key->type == KE_KEY) {
-               *keycode = key->keycode;
-               return 0;
+       if (dev->keycode) {
+               key = sparse_keymap_entry_from_scancode(dev, scancode);
+               if (key && key->type == KE_KEY) {
+                       *keycode = key->keycode;
+                       return 0;
+               }
        }
  
        return -EINVAL;
@@@ -86,17 -87,16 +88,16 @@@ static int sparse_keymap_setkeycode(str
        struct key_entry *key;
        int old_keycode;
  
-       if (keycode < 0 || keycode > KEY_MAX)
-               return -EINVAL;
-       key = sparse_keymap_entry_from_scancode(dev, scancode);
-       if (key && key->type == KE_KEY) {
-               old_keycode = key->keycode;
-               key->keycode = keycode;
-               set_bit(keycode, dev->keybit);
-               if (!sparse_keymap_entry_from_keycode(dev, old_keycode))
-                       clear_bit(old_keycode, dev->keybit);
-               return 0;
+       if (dev->keycode) {
+               key = sparse_keymap_entry_from_scancode(dev, scancode);
+               if (key && key->type == KE_KEY) {
+                       old_keycode = key->keycode;
+                       key->keycode = keycode;
+                       set_bit(keycode, dev->keybit);
+                       if (!sparse_keymap_entry_from_keycode(dev, old_keycode))
+                               clear_bit(old_keycode, dev->keybit);
+                       return 0;
+               }
        }
  
        return -EINVAL;
@@@ -164,7 -164,7 +165,7 @@@ int sparse_keymap_setup(struct input_de
        return 0;
  
   err_out:
-       kfree(keymap);
+       kfree(map);
        return error;
  
  }
@@@ -176,14 -176,27 +177,27 @@@ EXPORT_SYMBOL(sparse_keymap_setup)
   *
   * This function is used to free memory allocated by sparse keymap
   * in an input device that was set up by sparse_keymap_setup().
+  * NOTE: It is safe to cal this function while input device is
+  * still registered (however the drivers should care not to try to
+  * use freed keymap and thus have to shut off interrups/polling
+  * before freeing the keymap).
   */
  void sparse_keymap_free(struct input_dev *dev)
  {
+       unsigned long flags;
+       /*
+        * Take event lock to prevent racing with input_get_keycode()
+        * and input_set_keycode() if we are called while input device
+        * is still registered.
+        */
+       spin_lock_irqsave(&dev->event_lock, flags);
        kfree(dev->keycode);
        dev->keycode = NULL;
        dev->keycodemax = 0;
-       dev->getkeycode = NULL;
-       dev->setkeycode = NULL;
+       spin_unlock_irqrestore(&dev->event_lock, flags);
  }
  EXPORT_SYMBOL(sparse_keymap_free);