diff options
Diffstat (limited to 'drivers/input/serio/i8042.c')
-rw-r--r-- | drivers/input/serio/i8042.c | 38 |
1 files changed, 31 insertions, 7 deletions
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c index bc56e52b945f..1df02d25aca5 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c | |||
@@ -609,6 +609,8 @@ static irqreturn_t __init i8042_aux_test_irq(int irq, void *dev_id) | |||
609 | str = i8042_read_status(); | 609 | str = i8042_read_status(); |
610 | if (str & I8042_STR_OBF) { | 610 | if (str & I8042_STR_OBF) { |
611 | data = i8042_read_data(); | 611 | data = i8042_read_data(); |
612 | dbg("%02x <- i8042 (aux_test_irq, %s)", | ||
613 | data, str & I8042_STR_AUXDATA ? "aux" : "kbd"); | ||
612 | if (i8042_irq_being_tested && | 614 | if (i8042_irq_being_tested && |
613 | data == 0xa5 && (str & I8042_STR_AUXDATA)) | 615 | data == 0xa5 && (str & I8042_STR_AUXDATA)) |
614 | complete(&i8042_aux_irq_delivered); | 616 | complete(&i8042_aux_irq_delivered); |
@@ -750,6 +752,7 @@ static int __init i8042_check_aux(void) | |||
750 | * AUX IRQ was never delivered so we need to flush the controller to | 752 | * AUX IRQ was never delivered so we need to flush the controller to |
751 | * get rid of the byte we put there; otherwise keyboard may not work. | 753 | * get rid of the byte we put there; otherwise keyboard may not work. |
752 | */ | 754 | */ |
755 | dbg(" -- i8042 (aux irq test timeout)"); | ||
753 | i8042_flush(); | 756 | i8042_flush(); |
754 | retval = -1; | 757 | retval = -1; |
755 | } | 758 | } |
@@ -833,17 +836,32 @@ static int i8042_controller_selftest(void) | |||
833 | static int i8042_controller_init(void) | 836 | static int i8042_controller_init(void) |
834 | { | 837 | { |
835 | unsigned long flags; | 838 | unsigned long flags; |
839 | int n = 0; | ||
840 | unsigned char ctr[2]; | ||
836 | 841 | ||
837 | /* | 842 | /* |
838 | * Save the CTR for restoral on unload / reboot. | 843 | * Save the CTR for restore on unload / reboot. |
839 | */ | 844 | */ |
840 | 845 | ||
841 | if (i8042_command(&i8042_ctr, I8042_CMD_CTL_RCTR)) { | 846 | do { |
842 | printk(KERN_ERR "i8042.c: Can't read CTR while initializing i8042.\n"); | 847 | if (n >= 10) { |
843 | return -EIO; | 848 | printk(KERN_ERR |
844 | } | 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 | } | ||
845 | 861 | ||
846 | i8042_initial_ctr = i8042_ctr; | 862 | } while (n < 2 || ctr[0] != ctr[1]); |
863 | |||
864 | i8042_initial_ctr = i8042_ctr = ctr[0]; | ||
847 | 865 | ||
848 | /* | 866 | /* |
849 | * Disable the keyboard interface and interrupt. | 867 | * Disable the keyboard interface and interrupt. |
@@ -892,6 +910,12 @@ static int i8042_controller_init(void) | |||
892 | return -EIO; | 910 | return -EIO; |
893 | } | 911 | } |
894 | 912 | ||
913 | /* | ||
914 | * Flush whatever accumulated while we were disabling keyboard port. | ||
915 | */ | ||
916 | |||
917 | i8042_flush(); | ||
918 | |||
895 | return 0; | 919 | return 0; |
896 | } | 920 | } |
897 | 921 | ||
@@ -911,7 +935,7 @@ static void i8042_controller_reset(void) | |||
911 | i8042_ctr |= I8042_CTR_KBDDIS | I8042_CTR_AUXDIS; | 935 | i8042_ctr |= I8042_CTR_KBDDIS | I8042_CTR_AUXDIS; |
912 | i8042_ctr &= ~(I8042_CTR_KBDINT | I8042_CTR_AUXINT); | 936 | i8042_ctr &= ~(I8042_CTR_KBDINT | I8042_CTR_AUXINT); |
913 | 937 | ||
914 | if (i8042_command(&i8042_initial_ctr, I8042_CMD_CTL_WCTR)) | 938 | if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) |
915 | 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"); |
916 | 940 | ||
917 | /* | 941 | /* |