aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2009-11-06 02:00:48 -0500
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2009-11-06 02:00:48 -0500
commit02cee68998010c4a2cc2383c86babc2ecc737183 (patch)
tree13c6483472f672c3b2570b075ed2ad4fd4c5405e /drivers/input
parentf5ba35023697e54a24487bcd822194390a333893 (diff)
parentb419148e567728f6af0c3b01965c1cc141e3e13a (diff)
Merge commit 'v2.6.32-rc6' into next
Diffstat (limited to 'drivers/input')
-rw-r--r--drivers/input/input.c65
-rw-r--r--drivers/input/keyboard/atkbd.c132
-rw-r--r--drivers/input/keyboard/gpio_keys.c1
-rw-r--r--drivers/input/misc/Kconfig1
-rw-r--r--drivers/input/misc/hp_sdc_rtc.c2
-rw-r--r--drivers/input/mouse/logips2pp.c2
-rw-r--r--drivers/input/mouse/synaptics.c10
-rw-r--r--drivers/input/serio/i8042-x86ia64io.h13
-rw-r--r--drivers/input/serio/i8042.c35
9 files changed, 193 insertions, 68 deletions
diff --git a/drivers/input/input.c b/drivers/input/input.c
index c6f88ebb40c7..cc763c96fada 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -782,10 +782,29 @@ static unsigned int input_proc_devices_poll(struct file *file, poll_table *wait)
782 return 0; 782 return 0;
783} 783}
784 784
785union input_seq_state {
786 struct {
787 unsigned short pos;
788 bool mutex_acquired;
789 };
790 void *p;
791};
792
785static void *input_devices_seq_start(struct seq_file *seq, loff_t *pos) 793static void *input_devices_seq_start(struct seq_file *seq, loff_t *pos)
786{ 794{
787 if (mutex_lock_interruptible(&input_mutex)) 795 union input_seq_state *state = (union input_seq_state *)&seq->private;
788 return NULL; 796 int error;
797
798 /* We need to fit into seq->private pointer */
799 BUILD_BUG_ON(sizeof(union input_seq_state) != sizeof(seq->private));
800
801 error = mutex_lock_interruptible(&input_mutex);
802 if (error) {
803 state->mutex_acquired = false;
804 return ERR_PTR(error);
805 }
806
807 state->mutex_acquired = true;
789 808
790 return seq_list_start(&input_dev_list, *pos); 809 return seq_list_start(&input_dev_list, *pos);
791} 810}
@@ -795,9 +814,12 @@ static void *input_devices_seq_next(struct seq_file *seq, void *v, loff_t *pos)
795 return seq_list_next(v, &input_dev_list, pos); 814 return seq_list_next(v, &input_dev_list, pos);
796} 815}
797 816
798static void input_devices_seq_stop(struct seq_file *seq, void *v) 817static void input_seq_stop(struct seq_file *seq, void *v)
799{ 818{
800 mutex_unlock(&input_mutex); 819 union input_seq_state *state = (union input_seq_state *)&seq->private;
820
821 if (state->mutex_acquired)
822 mutex_unlock(&input_mutex);
801} 823}
802 824
803static void input_seq_print_bitmap(struct seq_file *seq, const char *name, 825static void input_seq_print_bitmap(struct seq_file *seq, const char *name,
@@ -861,7 +883,7 @@ static int input_devices_seq_show(struct seq_file *seq, void *v)
861static const struct seq_operations input_devices_seq_ops = { 883static const struct seq_operations input_devices_seq_ops = {
862 .start = input_devices_seq_start, 884 .start = input_devices_seq_start,
863 .next = input_devices_seq_next, 885 .next = input_devices_seq_next,
864 .stop = input_devices_seq_stop, 886 .stop = input_seq_stop,
865 .show = input_devices_seq_show, 887 .show = input_devices_seq_show,
866}; 888};
867 889
@@ -881,40 +903,49 @@ static const struct file_operations input_devices_fileops = {
881 903
882static void *input_handlers_seq_start(struct seq_file *seq, loff_t *pos) 904static void *input_handlers_seq_start(struct seq_file *seq, loff_t *pos)
883{ 905{
884 if (mutex_lock_interruptible(&input_mutex)) 906 union input_seq_state *state = (union input_seq_state *)&seq->private;
885 return NULL; 907 int error;
908
909 /* We need to fit into seq->private pointer */
910 BUILD_BUG_ON(sizeof(union input_seq_state) != sizeof(seq->private));
911
912 error = mutex_lock_interruptible(&input_mutex);
913 if (error) {
914 state->mutex_acquired = false;
915 return ERR_PTR(error);
916 }
917
918 state->mutex_acquired = true;
919 state->pos = *pos;
886 920
887 seq->private = (void *)(unsigned long)*pos;
888 return seq_list_start(&input_handler_list, *pos); 921 return seq_list_start(&input_handler_list, *pos);
889} 922}
890 923
891static void *input_handlers_seq_next(struct seq_file *seq, void *v, loff_t *pos) 924static void *input_handlers_seq_next(struct seq_file *seq, void *v, loff_t *pos)
892{ 925{
893 seq->private = (void *)(unsigned long)(*pos + 1); 926 union input_seq_state *state = (union input_seq_state *)&seq->private;
894 return seq_list_next(v, &input_handler_list, pos);
895}
896 927
897static void input_handlers_seq_stop(struct seq_file *seq, void *v) 928 state->pos = *pos + 1;
898{ 929 return seq_list_next(v, &input_handler_list, pos);
899 mutex_unlock(&input_mutex);
900} 930}
901 931
902static int input_handlers_seq_show(struct seq_file *seq, void *v) 932static int input_handlers_seq_show(struct seq_file *seq, void *v)
903{ 933{
904 struct input_handler *handler = container_of(v, struct input_handler, node); 934 struct input_handler *handler = container_of(v, struct input_handler, node);
935 union input_seq_state *state = (union input_seq_state *)&seq->private;
905 936
906 seq_printf(seq, "N: Number=%ld Name=%s", 937 seq_printf(seq, "N: Number=%u Name=%s", state->pos, handler->name);
907 (unsigned long)seq->private, handler->name);
908 if (handler->fops) 938 if (handler->fops)
909 seq_printf(seq, " Minor=%d", handler->minor); 939 seq_printf(seq, " Minor=%d", handler->minor);
910 seq_putc(seq, '\n'); 940 seq_putc(seq, '\n');
911 941
912 return 0; 942 return 0;
913} 943}
944
914static const struct seq_operations input_handlers_seq_ops = { 945static const struct seq_operations input_handlers_seq_ops = {
915 .start = input_handlers_seq_start, 946 .start = input_handlers_seq_start,
916 .next = input_handlers_seq_next, 947 .next = input_handlers_seq_next,
917 .stop = input_handlers_seq_stop, 948 .stop = input_seq_stop,
918 .show = input_handlers_seq_show, 949 .show = input_handlers_seq_show,
919}; 950};
920 951
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
index 4709e15af607..4452eabbee6d 100644
--- a/drivers/input/keyboard/atkbd.c
+++ b/drivers/input/keyboard/atkbd.c
@@ -233,6 +233,7 @@ struct atkbd {
233 */ 233 */
234static void (*atkbd_platform_fixup)(struct atkbd *, const void *data); 234static void (*atkbd_platform_fixup)(struct atkbd *, const void *data);
235static void *atkbd_platform_fixup_data; 235static void *atkbd_platform_fixup_data;
236static unsigned int (*atkbd_platform_scancode_fixup)(struct atkbd *, unsigned int);
236 237
237static ssize_t atkbd_attr_show_helper(struct device *dev, char *buf, 238static ssize_t atkbd_attr_show_helper(struct device *dev, char *buf,
238 ssize_t (*handler)(struct atkbd *, char *)); 239 ssize_t (*handler)(struct atkbd *, char *));
@@ -393,6 +394,9 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
393 394
394 input_event(dev, EV_MSC, MSC_RAW, code); 395 input_event(dev, EV_MSC, MSC_RAW, code);
395 396
397 if (atkbd_platform_scancode_fixup)
398 code = atkbd_platform_scancode_fixup(atkbd, code);
399
396 if (atkbd->translated) { 400 if (atkbd->translated) {
397 401
398 if (atkbd->emul || atkbd_need_xlate(atkbd->xl_bit, code)) { 402 if (atkbd->emul || atkbd_need_xlate(atkbd->xl_bit, code)) {
@@ -574,11 +578,22 @@ static void atkbd_event_work(struct work_struct *work)
574 578
575 mutex_lock(&atkbd->event_mutex); 579 mutex_lock(&atkbd->event_mutex);
576 580
577 if (test_and_clear_bit(ATKBD_LED_EVENT_BIT, &atkbd->event_mask)) 581 if (!atkbd->enabled) {
578 atkbd_set_leds(atkbd); 582 /*
583 * Serio ports are resumed asynchronously so while driver core
584 * thinks that device is already fully operational in reality
585 * it may not be ready yet. In this case we need to keep
586 * rescheduling till reconnect completes.
587 */
588 schedule_delayed_work(&atkbd->event_work,
589 msecs_to_jiffies(100));
590 } else {
591 if (test_and_clear_bit(ATKBD_LED_EVENT_BIT, &atkbd->event_mask))
592 atkbd_set_leds(atkbd);
579 593
580 if (test_and_clear_bit(ATKBD_REP_EVENT_BIT, &atkbd->event_mask)) 594 if (test_and_clear_bit(ATKBD_REP_EVENT_BIT, &atkbd->event_mask))
581 atkbd_set_repeat_rate(atkbd); 595 atkbd_set_repeat_rate(atkbd);
596 }
582 597
583 mutex_unlock(&atkbd->event_mutex); 598 mutex_unlock(&atkbd->event_mutex);
584} 599}
@@ -770,6 +785,30 @@ static int atkbd_select_set(struct atkbd *atkbd, int target_set, int allow_extra
770 return 3; 785 return 3;
771} 786}
772 787
788static int atkbd_reset_state(struct atkbd *atkbd)
789{
790 struct ps2dev *ps2dev = &atkbd->ps2dev;
791 unsigned char param[1];
792
793/*
794 * Set the LEDs to a predefined state (all off).
795 */
796
797 param[0] = 0;
798 if (ps2_command(ps2dev, param, ATKBD_CMD_SETLEDS))
799 return -1;
800
801/*
802 * Set autorepeat to fastest possible.
803 */
804
805 param[0] = 0;
806 if (ps2_command(ps2dev, param, ATKBD_CMD_SETREP))
807 return -1;
808
809 return 0;
810}
811
773static int atkbd_activate(struct atkbd *atkbd) 812static int atkbd_activate(struct atkbd *atkbd)
774{ 813{
775 struct ps2dev *ps2dev = &atkbd->ps2dev; 814 struct ps2dev *ps2dev = &atkbd->ps2dev;
@@ -852,29 +891,6 @@ static unsigned int atkbd_hp_forced_release_keys[] = {
852}; 891};
853 892
854/* 893/*
855 * Inventec system with broken key release on volume keys
856 */
857static unsigned int atkbd_inventec_forced_release_keys[] = {
858 0xae, 0xb0, -1U
859};
860
861/*
862 * Perform fixup for HP Pavilion ZV6100 laptop that doesn't generate release
863 * for its volume buttons
864 */
865static unsigned int atkbd_hp_zv6100_forced_release_keys[] = {
866 0xae, 0xb0, -1U
867};
868
869/*
870 * Perform fixup for HP (Compaq) Presario R4000 R4100 R4200 that don't generate
871 * release for their volume buttons
872 */
873static unsigned int atkbd_hp_r4000_forced_release_keys[] = {
874 0xae, 0xb0, -1U
875};
876
877/*
878 * Samsung NC10,NC20 with Fn+F? key release not working 894 * Samsung NC10,NC20 with Fn+F? key release not working
879 */ 895 */
880static unsigned int atkbd_samsung_forced_release_keys[] = { 896static unsigned int atkbd_samsung_forced_release_keys[] = {
@@ -882,14 +898,6 @@ static unsigned int atkbd_samsung_forced_release_keys[] = {
882}; 898};
883 899
884/* 900/*
885 * The volume up and volume down special keys on a Fujitsu Amilo PA 1510 laptop
886 * do not generate release events so we have to do it ourselves.
887 */
888static unsigned int atkbd_amilo_pa1510_forced_release_keys[] = {
889 0xb0, 0xae, -1U
890};
891
892/*
893 * Amilo Pi 3525 key release for Fn+Volume keys not working 901 * Amilo Pi 3525 key release for Fn+Volume keys not working
894 */ 902 */
895static unsigned int atkbd_amilo_pi3525_forced_release_keys[] = { 903static unsigned int atkbd_amilo_pi3525_forced_release_keys[] = {
@@ -911,6 +919,30 @@ static unsigned int atkdb_soltech_ta12_forced_release_keys[] = {
911}; 919};
912 920
913/* 921/*
922 * Many notebooks don't send key release event for volume up/down
923 * keys, with key list below common among them
924 */
925static unsigned int atkbd_volume_forced_release_keys[] = {
926 0xae, 0xb0, -1U
927};
928
929/*
930 * OQO 01+ multimedia keys (64--66) generate e0 6x upon release whereas
931 * they should be generating e4-e6 (0x80 | code).
932 */
933static unsigned int atkbd_oqo_01plus_scancode_fixup(struct atkbd *atkbd,
934 unsigned int code)
935{
936 if (atkbd->translated && atkbd->emul == 1 &&
937 (code == 0x64 || code == 0x65 || code == 0x66)) {
938 atkbd->emul = 0;
939 code |= 0x80;
940 }
941
942 return code;
943}
944
945/*
914 * atkbd_set_keycode_table() initializes keyboard's keycode table 946 * atkbd_set_keycode_table() initializes keyboard's keycode table
915 * according to the selected scancode set 947 * according to the selected scancode set
916 */ 948 */
@@ -1087,6 +1119,7 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv)
1087 } 1119 }
1088 1120
1089 atkbd->set = atkbd_select_set(atkbd, atkbd_set, atkbd_extra); 1121 atkbd->set = atkbd_select_set(atkbd, atkbd_set, atkbd_extra);
1122 atkbd_reset_state(atkbd);
1090 atkbd_activate(atkbd); 1123 atkbd_activate(atkbd);
1091 1124
1092 } else { 1125 } else {
@@ -1267,6 +1300,7 @@ static ssize_t atkbd_set_extra(struct atkbd *atkbd, const char *buf, size_t coun
1267 1300
1268 atkbd->dev = new_dev; 1301 atkbd->dev = new_dev;
1269 atkbd->set = atkbd_select_set(atkbd, atkbd->set, value); 1302 atkbd->set = atkbd_select_set(atkbd, atkbd->set, value);
1303 atkbd_reset_state(atkbd);
1270 atkbd_activate(atkbd); 1304 atkbd_activate(atkbd);
1271 atkbd_set_keycode_table(atkbd); 1305 atkbd_set_keycode_table(atkbd);
1272 atkbd_set_device_attrs(atkbd); 1306 atkbd_set_device_attrs(atkbd);
@@ -1513,6 +1547,13 @@ static int __init atkbd_setup_forced_release(const struct dmi_system_id *id)
1513 return 0; 1547 return 0;
1514} 1548}
1515 1549
1550static int __init atkbd_setup_scancode_fixup(const struct dmi_system_id *id)
1551{
1552 atkbd_platform_scancode_fixup = id->driver_data;
1553
1554 return 0;
1555}
1556
1516static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { 1557static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
1517 { 1558 {
1518 .ident = "Dell Laptop", 1559 .ident = "Dell Laptop",
@@ -1548,7 +1589,7 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
1548 DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion ZV6100"), 1589 DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion ZV6100"),
1549 }, 1590 },
1550 .callback = atkbd_setup_forced_release, 1591 .callback = atkbd_setup_forced_release,
1551 .driver_data = atkbd_hp_zv6100_forced_release_keys, 1592 .driver_data = atkbd_volume_forced_release_keys,
1552 }, 1593 },
1553 { 1594 {
1554 .ident = "HP Presario R4000", 1595 .ident = "HP Presario R4000",
@@ -1557,7 +1598,7 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
1557 DMI_MATCH(DMI_PRODUCT_NAME, "Presario R4000"), 1598 DMI_MATCH(DMI_PRODUCT_NAME, "Presario R4000"),
1558 }, 1599 },
1559 .callback = atkbd_setup_forced_release, 1600 .callback = atkbd_setup_forced_release,
1560 .driver_data = atkbd_hp_r4000_forced_release_keys, 1601 .driver_data = atkbd_volume_forced_release_keys,
1561 }, 1602 },
1562 { 1603 {
1563 .ident = "HP Presario R4100", 1604 .ident = "HP Presario R4100",
@@ -1566,7 +1607,7 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
1566 DMI_MATCH(DMI_PRODUCT_NAME, "Presario R4100"), 1607 DMI_MATCH(DMI_PRODUCT_NAME, "Presario R4100"),
1567 }, 1608 },
1568 .callback = atkbd_setup_forced_release, 1609 .callback = atkbd_setup_forced_release,
1569 .driver_data = atkbd_hp_r4000_forced_release_keys, 1610 .driver_data = atkbd_volume_forced_release_keys,
1570 }, 1611 },
1571 { 1612 {
1572 .ident = "HP Presario R4200", 1613 .ident = "HP Presario R4200",
@@ -1575,7 +1616,7 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
1575 DMI_MATCH(DMI_PRODUCT_NAME, "Presario R4200"), 1616 DMI_MATCH(DMI_PRODUCT_NAME, "Presario R4200"),
1576 }, 1617 },
1577 .callback = atkbd_setup_forced_release, 1618 .callback = atkbd_setup_forced_release,
1578 .driver_data = atkbd_hp_r4000_forced_release_keys, 1619 .driver_data = atkbd_volume_forced_release_keys,
1579 }, 1620 },
1580 { 1621 {
1581 .ident = "Inventec Symphony", 1622 .ident = "Inventec Symphony",
@@ -1584,7 +1625,7 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
1584 DMI_MATCH(DMI_PRODUCT_NAME, "SYMPHONY 6.0/7.0"), 1625 DMI_MATCH(DMI_PRODUCT_NAME, "SYMPHONY 6.0/7.0"),
1585 }, 1626 },
1586 .callback = atkbd_setup_forced_release, 1627 .callback = atkbd_setup_forced_release,
1587 .driver_data = atkbd_inventec_forced_release_keys, 1628 .driver_data = atkbd_volume_forced_release_keys,
1588 }, 1629 },
1589 { 1630 {
1590 .ident = "Samsung NC10", 1631 .ident = "Samsung NC10",
@@ -1620,7 +1661,7 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
1620 DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pa 1510"), 1661 DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pa 1510"),
1621 }, 1662 },
1622 .callback = atkbd_setup_forced_release, 1663 .callback = atkbd_setup_forced_release,
1623 .driver_data = atkbd_amilo_pa1510_forced_release_keys, 1664 .driver_data = atkbd_volume_forced_release_keys,
1624 }, 1665 },
1625 { 1666 {
1626 .ident = "Fujitsu Amilo Pi 3525", 1667 .ident = "Fujitsu Amilo Pi 3525",
@@ -1649,6 +1690,15 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
1649 .callback = atkbd_setup_forced_release, 1690 .callback = atkbd_setup_forced_release,
1650 .driver_data = atkdb_soltech_ta12_forced_release_keys, 1691 .driver_data = atkdb_soltech_ta12_forced_release_keys,
1651 }, 1692 },
1693 {
1694 .ident = "OQO Model 01+",
1695 .matches = {
1696 DMI_MATCH(DMI_SYS_VENDOR, "OQO"),
1697 DMI_MATCH(DMI_PRODUCT_NAME, "ZEPTO"),
1698 },
1699 .callback = atkbd_setup_scancode_fixup,
1700 .driver_data = atkbd_oqo_01plus_scancode_fixup,
1701 },
1652 { } 1702 { }
1653}; 1703};
1654 1704
diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c
index a88aff3816a0..77d130914259 100644
--- a/drivers/input/keyboard/gpio_keys.c
+++ b/drivers/input/keyboard/gpio_keys.c
@@ -147,6 +147,7 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev)
147 } 147 }
148 148
149 error = request_irq(irq, gpio_keys_isr, 149 error = request_irq(irq, gpio_keys_isr,
150 IRQF_SHARED |
150 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, 151 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
151 button->desc ? button->desc : "gpio_keys", 152 button->desc ? button->desc : "gpio_keys",
152 bdata); 153 bdata);
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index 02f4f8f1db6f..a9bb2544b2de 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -227,6 +227,7 @@ config INPUT_WINBOND_CIR
227 depends on X86 && PNP 227 depends on X86 && PNP
228 select NEW_LEDS 228 select NEW_LEDS
229 select LEDS_CLASS 229 select LEDS_CLASS
230 select LEDS_TRIGGERS
230 select BITREVERSE 231 select BITREVERSE
231 help 232 help
232 Say Y here if you want to use the IR remote functionality found 233 Say Y here if you want to use the IR remote functionality found
diff --git a/drivers/input/misc/hp_sdc_rtc.c b/drivers/input/misc/hp_sdc_rtc.c
index 216a559f55ea..ea821b546969 100644
--- a/drivers/input/misc/hp_sdc_rtc.c
+++ b/drivers/input/misc/hp_sdc_rtc.c
@@ -209,7 +209,7 @@ static inline int hp_sdc_rtc_read_rt(struct timeval *res) {
209 209
210/* Read the i8042 fast handshake timer */ 210/* Read the i8042 fast handshake timer */
211static inline int hp_sdc_rtc_read_fhs(struct timeval *res) { 211static inline int hp_sdc_rtc_read_fhs(struct timeval *res) {
212 uint64_t raw; 212 int64_t raw;
213 unsigned int tenms; 213 unsigned int tenms;
214 214
215 raw = hp_sdc_rtc_read_i8042timer(HP_SDC_CMD_LOAD_FHS, 2); 215 raw = hp_sdc_rtc_read_i8042timer(HP_SDC_CMD_LOAD_FHS, 2);
diff --git a/drivers/input/mouse/logips2pp.c b/drivers/input/mouse/logips2pp.c
index de745d751162..ab5dc5f5fd83 100644
--- a/drivers/input/mouse/logips2pp.c
+++ b/drivers/input/mouse/logips2pp.c
@@ -219,7 +219,7 @@ static const struct ps2pp_info *get_model_info(unsigned char model)
219 PS2PP_WHEEL | PS2PP_SIDE_BTN | PS2PP_TASK_BTN | 219 PS2PP_WHEEL | PS2PP_SIDE_BTN | PS2PP_TASK_BTN |
220 PS2PP_EXTRA_BTN | PS2PP_NAV_BTN | PS2PP_HWHEEL }, 220 PS2PP_EXTRA_BTN | PS2PP_NAV_BTN | PS2PP_HWHEEL },
221 { 72, PS2PP_KIND_TRACKMAN, 0 }, /* T-CH11: TrackMan Marble */ 221 { 72, PS2PP_KIND_TRACKMAN, 0 }, /* T-CH11: TrackMan Marble */
222 { 73, 0, PS2PP_SIDE_BTN }, 222 { 73, PS2PP_KIND_TRACKMAN, PS2PP_SIDE_BTN }, /* TrackMan FX */
223 { 75, PS2PP_KIND_WHEEL, PS2PP_WHEEL }, 223 { 75, PS2PP_KIND_WHEEL, PS2PP_WHEEL },
224 { 76, PS2PP_KIND_WHEEL, PS2PP_WHEEL }, 224 { 76, PS2PP_KIND_WHEEL, PS2PP_WHEEL },
225 { 79, PS2PP_KIND_TRACKMAN, PS2PP_WHEEL }, /* TrackMan with wheel */ 225 { 79, PS2PP_KIND_TRACKMAN, PS2PP_WHEEL }, /* TrackMan with wheel */
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
index b66ff1ac7dea..f4a61252bcc9 100644
--- a/drivers/input/mouse/synaptics.c
+++ b/drivers/input/mouse/synaptics.c
@@ -652,6 +652,16 @@ static const struct dmi_system_id toshiba_dmi_table[] = {
652 DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), 652 DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
653 DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE M300"), 653 DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE M300"),
654 }, 654 },
655
656 },
657 {
658 .ident = "Toshiba Portege M300",
659 .matches = {
660 DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
661 DMI_MATCH(DMI_PRODUCT_NAME, "Portable PC"),
662 DMI_MATCH(DMI_PRODUCT_VERSION, "Version 1.0"),
663 },
664
655 }, 665 },
656 { } 666 { }
657}; 667};
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h
index a39bc4eb902b..a537925f7651 100644
--- a/drivers/input/serio/i8042-x86ia64io.h
+++ b/drivers/input/serio/i8042-x86ia64io.h
@@ -327,6 +327,17 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = {
327 }, 327 },
328 }, 328 },
329 { 329 {
330 /*
331 * Reset and GET ID commands issued via KBD port are
332 * sometimes being delivered to AUX3.
333 */
334 .ident = "Sony Vaio FZ-240E",
335 .matches = {
336 DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
337 DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FZ240E"),
338 },
339 },
340 {
330 .ident = "Amoi M636/A737", 341 .ident = "Amoi M636/A737",
331 .matches = { 342 .matches = {
332 DMI_MATCH(DMI_SYS_VENDOR, "Amoi Electronics CO.,LTD."), 343 DMI_MATCH(DMI_SYS_VENDOR, "Amoi Electronics CO.,LTD."),
@@ -661,7 +672,7 @@ static void i8042_pnp_exit(void)
661static int __init i8042_pnp_init(void) 672static int __init i8042_pnp_init(void)
662{ 673{
663 char kbd_irq_str[4] = { 0 }, aux_irq_str[4] = { 0 }; 674 char kbd_irq_str[4] = { 0 }, aux_irq_str[4] = { 0 };
664 int pnp_data_busted = false; 675 bool pnp_data_busted = false;
665 int err; 676 int err;
666 677
667#ifdef CONFIG_X86 678#ifdef CONFIG_X86
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
index a31578170ccc..1df02d25aca5 100644
--- a/drivers/input/serio/i8042.c
+++ b/drivers/input/serio/i8042.c
@@ -836,17 +836,32 @@ static int i8042_controller_selftest(void)
836static int i8042_controller_init(void) 836static int i8042_controller_init(void)
837{ 837{
838 unsigned long flags; 838 unsigned long flags;
839 int n = 0;
840 unsigned char ctr[2];
839 841
840/* 842/*
841 * Save the CTR for restoral on unload / reboot. 843 * Save the CTR for restore on unload / reboot.
842 */ 844 */
843 845
844 if (i8042_command(&i8042_ctr, I8042_CMD_CTL_RCTR)) { 846 do {
845 printk(KERN_ERR "i8042.c: Can't read CTR while initializing i8042.\n"); 847 if (n >= 10) {
846 return -EIO; 848 printk(KERN_ERR
847 } 849 "i8042.c: Unable to get stable CTR read.\n");
850 return -EIO;
851 }
852
853 if (n != 0)
854 udelay(50);
855
856 if (i8042_command(&ctr[n++ % 2], I8042_CMD_CTL_RCTR)) {
857 printk(KERN_ERR
858 "i8042.c: Can't read CTR while initializing i8042.\n");
859 return -EIO;
860 }
848 861
849 i8042_initial_ctr = i8042_ctr; 862 } while (n < 2 || ctr[0] != ctr[1]);
863
864 i8042_initial_ctr = i8042_ctr = ctr[0];
850 865
851/* 866/*
852 * Disable the keyboard interface and interrupt. 867 * Disable the keyboard interface and interrupt.
@@ -895,6 +910,12 @@ static int i8042_controller_init(void)
895 return -EIO; 910 return -EIO;
896 } 911 }
897 912
913/*
914 * Flush whatever accumulated while we were disabling keyboard port.
915 */
916
917 i8042_flush();
918
898 return 0; 919 return 0;
899} 920}
900 921
@@ -914,7 +935,7 @@ static void i8042_controller_reset(void)
914 i8042_ctr |= I8042_CTR_KBDDIS | I8042_CTR_AUXDIS; 935 i8042_ctr |= I8042_CTR_KBDDIS | I8042_CTR_AUXDIS;
915 i8042_ctr &= ~(I8042_CTR_KBDINT | I8042_CTR_AUXINT); 936 i8042_ctr &= ~(I8042_CTR_KBDINT | I8042_CTR_AUXINT);
916 937
917 if (i8042_command(&i8042_initial_ctr, I8042_CMD_CTL_WCTR)) 938 if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR))
918 printk(KERN_WARNING "i8042.c: Can't write CTR while resetting.\n"); 939 printk(KERN_WARNING "i8042.c: Can't write CTR while resetting.\n");
919 940
920/* 941/*