The following commit has been merged in the linux branch: commit be8db0b843d4eef193e996c3e31aabf15b2d7004 Merge: 422b42fa79fa2825dc7b272ee8d52aa4bac37113 3776989d2339c58ff8d8421e754603f186d7439b Author: Linus Torvalds torvalds@linux-foundation.org Date: Thu Oct 22 08:27:12 2009 +0900
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
* '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
diff --combined drivers/input/input.c index c6f88eb,60a4eaa..cc763c9 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@@ -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) @@@ -1289,6 -1318,7 +1320,6 @@@ } }
-#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);
diff --combined drivers/input/keyboard/atkbd.c index 4709e15,271c0b7..a651237 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c @@@ -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; @@@ -852,29 -887,6 +887,6 @@@ static unsigned int atkbd_hp_forced_rel };
/* - * 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 */ static unsigned int atkbd_samsung_forced_release_keys[] = { @@@ -882,14 -894,6 +894,6 @@@ };
/* - * 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 */ static unsigned int atkbd_amilo_pi3525_forced_release_keys[] = { @@@ -911,6 -915,14 +915,14 @@@ static unsigned int atkdb_soltech_ta12_ };
/* + * 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", @@@ -1557,7 -1571,7 +1571,7 @@@ 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", @@@ -1566,7 -1580,7 +1580,7 @@@ 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", @@@ -1575,7 -1589,7 +1589,7 @@@ 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", @@@ -1584,7 -1598,7 +1598,7 @@@ 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", @@@ -1620,7 -1634,7 +1634,7 @@@ 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",