diff options
| author | Arjan van de Ven <arjan@linux.intel.com> | 2009-04-09 14:36:50 -0400 |
|---|---|---|
| committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2009-04-11 20:09:12 -0400 |
| commit | 5ea2fc6491631d2c3f346dcb0d9d6edd44ccf4cd (patch) | |
| tree | f4ffb679ac763a312efb912d195e8ebc56e7d87b /drivers | |
| parent | 59cc1dd97ca9ac0363ef2f770901fbd86e2b970a (diff) | |
Input: i8042 - introduce a tougher reset
Some touchpads don't reset right the first time (MSI Wind U-100 for
example). This patch will retry the reset up to 5 times.
In addition, on x86, we don't fail entire i8042 initialization if
controller reset fails in hope that keyboard port will still be
functional and user will still get a working keyboard. This is
especially important on netbooks.
Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/input/serio/i8042.c | 37 |
1 files changed, 29 insertions, 8 deletions
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c index 170f71ee5772..3cffb704e374 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c | |||
| @@ -712,22 +712,43 @@ static int i8042_controller_check(void) | |||
| 712 | static int i8042_controller_selftest(void) | 712 | static int i8042_controller_selftest(void) |
| 713 | { | 713 | { |
| 714 | unsigned char param; | 714 | unsigned char param; |
| 715 | int i = 0; | ||
| 715 | 716 | ||
| 716 | if (!i8042_reset) | 717 | if (!i8042_reset) |
| 717 | return 0; | 718 | return 0; |
| 718 | 719 | ||
| 719 | if (i8042_command(¶m, I8042_CMD_CTL_TEST)) { | 720 | /* |
| 720 | printk(KERN_ERR "i8042.c: i8042 controller self test timeout.\n"); | 721 | * We try this 5 times; on some really fragile systems this does not |
| 721 | return -ENODEV; | 722 | * take the first time... |
| 722 | } | 723 | */ |
| 724 | do { | ||
| 725 | |||
| 726 | if (i8042_command(¶m, I8042_CMD_CTL_TEST)) { | ||
| 727 | printk(KERN_ERR "i8042.c: i8042 controller self test timeout.\n"); | ||
| 728 | return -ENODEV; | ||
| 729 | } | ||
| 730 | |||
| 731 | if (param == I8042_RET_CTL_TEST) | ||
| 732 | return 0; | ||
| 723 | 733 | ||
| 724 | if (param != I8042_RET_CTL_TEST) { | ||
| 725 | printk(KERN_ERR "i8042.c: i8042 controller selftest failed. (%#x != %#x)\n", | 734 | printk(KERN_ERR "i8042.c: i8042 controller selftest failed. (%#x != %#x)\n", |
| 726 | param, I8042_RET_CTL_TEST); | 735 | param, I8042_RET_CTL_TEST); |
| 727 | return -EIO; | 736 | msleep(50); |
| 728 | } | 737 | } while (i++ < 5); |
| 729 | 738 | ||
| 739 | #ifdef CONFIG_X86 | ||
| 740 | /* | ||
| 741 | * On x86, we don't fail entire i8042 initialization if controller | ||
| 742 | * reset fails in hopes that keyboard port will still be functional | ||
| 743 | * and user will still get a working keyboard. This is especially | ||
| 744 | * important on netbooks. On other arches we trust hardware more. | ||
| 745 | */ | ||
| 746 | printk(KERN_INFO | ||
| 747 | "i8042: giving up on controller selftest, continuing anyway...\n"); | ||
| 730 | return 0; | 748 | return 0; |
| 749 | #else | ||
| 750 | return -EIO; | ||
| 751 | #endif | ||
| 731 | } | 752 | } |
| 732 | 753 | ||
| 733 | /* | 754 | /* |
