]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/commitdiff
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 21 Oct 2009 23:27:12 +0000 (08:27 +0900)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 21 Oct 2009 23:27:12 +0000 (08:27 +0900)
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input:
  Input: hp_sdc_rtc - fix test in hp_sdc_rtc_read_rt()
  Input: atkbd - consolidate force release quirks for volume keys
  Input: logips2pp - model 73 is actually TrackMan FX
  Input: i8042 - add Sony Vaio VGN-FZ240E to the nomux list
  Input: fix locking issue in /proc/bus/input/ handlers
  Input: atkbd - postpone restoring LED/repeat rate at resume
  Input: atkbd - restore resetting LED state at startup
  Input: i8042 - make pnp_data_busted variable boolean instead of int
  Input: synaptics - add another Protege M300 to rate blacklist

1  2 
drivers/input/input.c
drivers/input/keyboard/atkbd.c

diff --combined drivers/input/input.c
index c6f88ebb40c766e21c17104cdbbe12563ed075a7,60a4eaabb7d74d8684d7f38a152a707598097454..cc763c96fadadf0565048a2a897d0f6202d81f09
@@@ -17,7 -17,6 +17,7 @@@
  #include <linux/random.h>
  #include <linux/major.h>
  #include <linux/proc_fs.h>
 +#include <linux/sched.h>
  #include <linux/seq_file.h>
  #include <linux/poll.h>
  #include <linux/device.h>
@@@ -782,10 -781,29 +782,29 @@@ static unsigned int input_proc_devices_
        return 0;
  }
  
+ union input_seq_state {
+       struct {
+               unsigned short pos;
+               bool mutex_acquired;
+       };
+       void *p;
+ };
  static void *input_devices_seq_start(struct seq_file *seq, loff_t *pos)
  {
-       if (mutex_lock_interruptible(&input_mutex))
-               return NULL;
+       union input_seq_state *state = (union input_seq_state *)&seq->private;
+       int error;
+       /* We need to fit into seq->private pointer */
+       BUILD_BUG_ON(sizeof(union input_seq_state) != sizeof(seq->private));
+       error = mutex_lock_interruptible(&input_mutex);
+       if (error) {
+               state->mutex_acquired = false;
+               return ERR_PTR(error);
+       }
+       state->mutex_acquired = true;
  
        return seq_list_start(&input_dev_list, *pos);
  }
@@@ -795,9 -813,12 +814,12 @@@ static void *input_devices_seq_next(str
        return seq_list_next(v, &input_dev_list, pos);
  }
  
- static void input_devices_seq_stop(struct seq_file *seq, void *v)
+ static void input_seq_stop(struct seq_file *seq, void *v)
  {
-       mutex_unlock(&input_mutex);
+       union input_seq_state *state = (union input_seq_state *)&seq->private;
+       if (state->mutex_acquired)
+               mutex_unlock(&input_mutex);
  }
  
  static void input_seq_print_bitmap(struct seq_file *seq, const char *name,
@@@ -861,7 -882,7 +883,7 @@@ static int input_devices_seq_show(struc
  static const struct seq_operations input_devices_seq_ops = {
        .start  = input_devices_seq_start,
        .next   = input_devices_seq_next,
-       .stop   = input_devices_seq_stop,
+       .stop   = input_seq_stop,
        .show   = input_devices_seq_show,
  };
  
@@@ -881,40 -902,49 +903,49 @@@ static const struct file_operations inp
  
  static void *input_handlers_seq_start(struct seq_file *seq, loff_t *pos)
  {
-       if (mutex_lock_interruptible(&input_mutex))
-               return NULL;
+       union input_seq_state *state = (union input_seq_state *)&seq->private;
+       int error;
+       /* We need to fit into seq->private pointer */
+       BUILD_BUG_ON(sizeof(union input_seq_state) != sizeof(seq->private));
+       error = mutex_lock_interruptible(&input_mutex);
+       if (error) {
+               state->mutex_acquired = false;
+               return ERR_PTR(error);
+       }
+       state->mutex_acquired = true;
+       state->pos = *pos;
  
-       seq->private = (void *)(unsigned long)*pos;
        return seq_list_start(&input_handler_list, *pos);
  }
  
  static void *input_handlers_seq_next(struct seq_file *seq, void *v, loff_t *pos)
  {
-       seq->private = (void *)(unsigned long)(*pos + 1);
-       return seq_list_next(v, &input_handler_list, pos);
- }
+       union input_seq_state *state = (union input_seq_state *)&seq->private;
  
- static void input_handlers_seq_stop(struct seq_file *seq, void *v)
- {
-       mutex_unlock(&input_mutex);
+       state->pos = *pos + 1;
+       return seq_list_next(v, &input_handler_list, pos);
  }
  
  static int input_handlers_seq_show(struct seq_file *seq, void *v)
  {
        struct input_handler *handler = container_of(v, struct input_handler, node);
+       union input_seq_state *state = (union input_seq_state *)&seq->private;
  
-       seq_printf(seq, "N: Number=%ld Name=%s",
-                  (unsigned long)seq->private, handler->name);
+       seq_printf(seq, "N: Number=%u Name=%s", state->pos, handler->name);
        if (handler->fops)
                seq_printf(seq, " Minor=%d", handler->minor);
        seq_putc(seq, '\n');
  
        return 0;
  }
  static const struct seq_operations input_handlers_seq_ops = {
        .start  = input_handlers_seq_start,
        .next   = input_handlers_seq_next,
-       .stop   = input_handlers_seq_stop,
+       .stop   = input_seq_stop,
        .show   = input_handlers_seq_show,
  };
  
@@@ -1146,7 -1176,7 +1177,7 @@@ static struct attribute_group input_dev
        .attrs  = input_dev_caps_attrs,
  };
  
 -static struct attribute_group *input_dev_attr_groups[] = {
 +static const struct attribute_group *input_dev_attr_groups[] = {
        &input_dev_attr_group,
        &input_dev_id_attr_group,
        &input_dev_caps_attr_group,
@@@ -1274,7 -1304,6 +1305,7 @@@ static int input_dev_uevent(struct devi
                }                                               \
        } while (0)
  
 +#ifdef CONFIG_PM
  static void input_dev_reset(struct input_dev *dev, bool activate)
  {
        if (!dev->event)
        }
  }
  
 -#ifdef CONFIG_PM
  static int input_dev_suspend(struct device *dev)
  {
        struct input_dev *input_dev = to_input_dev(dev);
@@@ -1328,14 -1358,14 +1359,14 @@@ static struct device_type input_dev_typ
  #endif
  };
  
 -static char *input_nodename(struct device *dev)
 +static char *input_devnode(struct device *dev, mode_t *mode)
  {
        return kasprintf(GFP_KERNEL, "input/%s", dev_name(dev));
  }
  
  struct class input_class = {
        .name           = "input",
 -      .nodename       = input_nodename,
 +      .devnode        = input_devnode,
  };
  EXPORT_SYMBOL_GPL(input_class);
  
index 4709e15af6070522dcf03516acb058bd024b07d7,271c0b7045c3b9df4767ab6edcedc3066ebf9018..a6512372c7a301666f6347ee3d84d82fada5f707
@@@ -229,7 -229,7 +229,7 @@@ struct atkbd 
  };
  
  /*
 - * System-specific ketymap fixup routine
 + * System-specific keymap fixup routine
   */
  static void (*atkbd_platform_fixup)(struct atkbd *, const void *data);
  static void *atkbd_platform_fixup_data;
@@@ -574,11 -574,22 +574,22 @@@ static void atkbd_event_work(struct wor
  
        mutex_lock(&atkbd->event_mutex);
  
-       if (test_and_clear_bit(ATKBD_LED_EVENT_BIT, &atkbd->event_mask))
-               atkbd_set_leds(atkbd);
+       if (!atkbd->enabled) {
+               /*
+                * Serio ports are resumed asynchronously so while driver core
+                * thinks that device is already fully operational in reality
+                * it may not be ready yet. In this case we need to keep
+                * rescheduling till reconnect completes.
+                */
+               schedule_delayed_work(&atkbd->event_work,
+                                       msecs_to_jiffies(100));
+       } else {
+               if (test_and_clear_bit(ATKBD_LED_EVENT_BIT, &atkbd->event_mask))
+                       atkbd_set_leds(atkbd);
  
-       if (test_and_clear_bit(ATKBD_REP_EVENT_BIT, &atkbd->event_mask))
-               atkbd_set_repeat_rate(atkbd);
+               if (test_and_clear_bit(ATKBD_REP_EVENT_BIT, &atkbd->event_mask))
+                       atkbd_set_repeat_rate(atkbd);
+       }
  
        mutex_unlock(&atkbd->event_mutex);
  }
@@@ -770,6 -781,30 +781,30 @@@ static int atkbd_select_set(struct atkb
        return 3;
  }
  
+ static int atkbd_reset_state(struct atkbd *atkbd)
+ {
+         struct ps2dev *ps2dev = &atkbd->ps2dev;
+       unsigned char param[1];
+ /*
+  * Set the LEDs to a predefined state (all off).
+  */
+       param[0] = 0;
+       if (ps2_command(ps2dev, param, ATKBD_CMD_SETLEDS))
+               return -1;
+ /*
+  * Set autorepeat to fastest possible.
+  */
+       param[0] = 0;
+       if (ps2_command(ps2dev, param, ATKBD_CMD_SETREP))
+               return -1;
+       return 0;
+ }
  static int atkbd_activate(struct atkbd *atkbd)
  {
        struct ps2dev *ps2dev = &atkbd->ps2dev;
@@@ -851,29 -886,6 +886,6 @@@ static unsigned int atkbd_hp_forced_rel
        0x94, -1U
  };
  
- /*
-  * Inventec system with broken key release on volume keys
-  */
- static unsigned int atkbd_inventec_forced_release_keys[] = {
-       0xae, 0xb0, -1U
- };
- /*
-  * Perform fixup for HP Pavilion ZV6100 laptop that doesn't generate release
-  * for its volume buttons
-  */
- static unsigned int atkbd_hp_zv6100_forced_release_keys[] = {
-       0xae, 0xb0, -1U
- };
- /*
-  * Perform fixup for HP (Compaq) Presario R4000 R4100 R4200 that don't generate
-  * release for their volume buttons
-  */
- static unsigned int atkbd_hp_r4000_forced_release_keys[] = {
-       0xae, 0xb0, -1U
- };
  /*
   * Samsung NC10,NC20 with Fn+F? key release not working
   */
@@@ -881,14 -893,6 +893,6 @@@ static unsigned int atkbd_samsung_force
        0x82, 0x83, 0x84, 0x86, 0x88, 0x89, 0xb3, 0xf7, 0xf9, -1U
  };
  
- /*
-  * The volume up and volume down special keys on a Fujitsu Amilo PA 1510 laptop
-  * do not generate release events so we have to do it ourselves.
-  */
- static unsigned int atkbd_amilo_pa1510_forced_release_keys[] = {
-       0xb0, 0xae, -1U
- };
  /*
   * Amilo Pi 3525 key release for Fn+Volume keys not working
   */
@@@ -910,6 -914,14 +914,14 @@@ static unsigned int atkdb_soltech_ta12_
        0xa0, 0xae, 0xb0, -1U
  };
  
+ /*
+  * Many notebooks don't send key release event for volume up/down
+  * keys, with key list below common among them
+  */
+ static unsigned int atkbd_volume_forced_release_keys[] = {
+       0xae, 0xb0, -1U
+ };
  /*
   * atkbd_set_keycode_table() initializes keyboard's keycode table
   * according to the selected scancode set
@@@ -1087,6 -1099,7 +1099,7 @@@ static int atkbd_connect(struct serio *
                }
  
                atkbd->set = atkbd_select_set(atkbd, atkbd_set, atkbd_extra);
+               atkbd_reset_state(atkbd);
                atkbd_activate(atkbd);
  
        } else {
@@@ -1267,6 -1280,7 +1280,7 @@@ static ssize_t atkbd_set_extra(struct a
  
                atkbd->dev = new_dev;
                atkbd->set = atkbd_select_set(atkbd, atkbd->set, value);
+               atkbd_reset_state(atkbd);
                atkbd_activate(atkbd);
                atkbd_set_keycode_table(atkbd);
                atkbd_set_device_attrs(atkbd);
@@@ -1548,7 -1562,7 +1562,7 @@@ static struct dmi_system_id atkbd_dmi_q
                        DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion ZV6100"),
                },
                .callback = atkbd_setup_forced_release,
-               .driver_data = atkbd_hp_zv6100_forced_release_keys,
+               .driver_data = atkbd_volume_forced_release_keys,
        },
        {
                .ident = "HP Presario R4000",
                        DMI_MATCH(DMI_PRODUCT_NAME, "Presario R4000"),
                },
                .callback = atkbd_setup_forced_release,
-               .driver_data = atkbd_hp_r4000_forced_release_keys,
+               .driver_data = atkbd_volume_forced_release_keys,
        },
        {
                .ident = "HP Presario R4100",
                        DMI_MATCH(DMI_PRODUCT_NAME, "Presario R4100"),
                },
                .callback = atkbd_setup_forced_release,
-               .driver_data = atkbd_hp_r4000_forced_release_keys,
+               .driver_data = atkbd_volume_forced_release_keys,
        },
        {
                .ident = "HP Presario R4200",
                        DMI_MATCH(DMI_PRODUCT_NAME, "Presario R4200"),
                },
                .callback = atkbd_setup_forced_release,
-               .driver_data = atkbd_hp_r4000_forced_release_keys,
+               .driver_data = atkbd_volume_forced_release_keys,
        },
        {
                .ident = "Inventec Symphony",
                        DMI_MATCH(DMI_PRODUCT_NAME, "SYMPHONY 6.0/7.0"),
                },
                .callback = atkbd_setup_forced_release,
-               .driver_data = atkbd_inventec_forced_release_keys,
+               .driver_data = atkbd_volume_forced_release_keys,
        },
        {
                .ident = "Samsung NC10",
                        DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pa 1510"),
                },
                .callback = atkbd_setup_forced_release,
-               .driver_data = atkbd_amilo_pa1510_forced_release_keys,
+               .driver_data = atkbd_volume_forced_release_keys,
        },
        {
                .ident = "Fujitsu Amilo Pi 3525",