diff options
Diffstat (limited to 'drivers/input/serio/i8042.c')
-rw-r--r-- | drivers/input/serio/i8042.c | 56 |
1 files changed, 29 insertions, 27 deletions
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c index c3fdfc1f342a..b90a2cddc8a1 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c | |||
@@ -724,7 +724,7 @@ static int i8042_controller_init(void) | |||
724 | if (~i8042_read_status() & I8042_STR_KEYLOCK) { | 724 | if (~i8042_read_status() & I8042_STR_KEYLOCK) { |
725 | if (i8042_unlock) | 725 | if (i8042_unlock) |
726 | i8042_ctr |= I8042_CTR_IGNKEYLOCK; | 726 | i8042_ctr |= I8042_CTR_IGNKEYLOCK; |
727 | else | 727 | else |
728 | printk(KERN_WARNING "i8042.c: Warning: Keylock active.\n"); | 728 | printk(KERN_WARNING "i8042.c: Warning: Keylock active.\n"); |
729 | } | 729 | } |
730 | spin_unlock_irqrestore(&i8042_lock, flags); | 730 | spin_unlock_irqrestore(&i8042_lock, flags); |
@@ -791,27 +791,6 @@ static void i8042_controller_reset(void) | |||
791 | 791 | ||
792 | 792 | ||
793 | /* | 793 | /* |
794 | * Here we try to reset everything back to a state in which the BIOS will be | ||
795 | * able to talk to the hardware when rebooting. | ||
796 | */ | ||
797 | |||
798 | static void i8042_controller_cleanup(void) | ||
799 | { | ||
800 | int i; | ||
801 | |||
802 | /* | ||
803 | * Reset anything that is connected to the ports. | ||
804 | */ | ||
805 | |||
806 | for (i = 0; i < I8042_NUM_PORTS; i++) | ||
807 | if (i8042_ports[i].serio) | ||
808 | serio_cleanup(i8042_ports[i].serio); | ||
809 | |||
810 | i8042_controller_reset(); | ||
811 | } | ||
812 | |||
813 | |||
814 | /* | ||
815 | * i8042_panic_blink() will flash the keyboard LEDs and is called when | 794 | * i8042_panic_blink() will flash the keyboard LEDs and is called when |
816 | * kernel panics. Flashing LEDs is useful for users running X who may | 795 | * kernel panics. Flashing LEDs is useful for users running X who may |
817 | * not see the console and will help distingushing panics from "real" | 796 | * not see the console and will help distingushing panics from "real" |
@@ -857,13 +836,22 @@ static long i8042_panic_blink(long count) | |||
857 | 836 | ||
858 | #undef DELAY | 837 | #undef DELAY |
859 | 838 | ||
839 | #ifdef CONFIG_PM | ||
860 | /* | 840 | /* |
861 | * Here we try to restore the original BIOS settings | 841 | * Here we try to restore the original BIOS settings. We only want to |
842 | * do that once, when we really suspend, not when we taking memory | ||
843 | * snapshot for swsusp (in this case we'll perform required cleanup | ||
844 | * as part of shutdown process). | ||
862 | */ | 845 | */ |
863 | 846 | ||
864 | static int i8042_suspend(struct platform_device *dev, pm_message_t state) | 847 | static int i8042_suspend(struct platform_device *dev, pm_message_t state) |
865 | { | 848 | { |
866 | i8042_controller_cleanup(); | 849 | if (dev->dev.power.power_state.event != state.event) { |
850 | if (state.event == PM_EVENT_SUSPEND) | ||
851 | i8042_controller_reset(); | ||
852 | |||
853 | dev->dev.power.power_state = state; | ||
854 | } | ||
867 | 855 | ||
868 | return 0; | 856 | return 0; |
869 | } | 857 | } |
@@ -877,6 +865,12 @@ static int i8042_resume(struct platform_device *dev) | |||
877 | { | 865 | { |
878 | int error; | 866 | int error; |
879 | 867 | ||
868 | /* | ||
869 | * Do not bother with restoring state if we haven't suspened yet | ||
870 | */ | ||
871 | if (dev->dev.power.power_state.event == PM_EVENT_ON) | ||
872 | return 0; | ||
873 | |||
880 | error = i8042_controller_check(); | 874 | error = i8042_controller_check(); |
881 | if (error) | 875 | if (error) |
882 | return error; | 876 | return error; |
@@ -886,9 +880,12 @@ static int i8042_resume(struct platform_device *dev) | |||
886 | return error; | 880 | return error; |
887 | 881 | ||
888 | /* | 882 | /* |
889 | * Restore pre-resume CTR value and disable all ports | 883 | * Restore original CTR value and disable all ports |
890 | */ | 884 | */ |
891 | 885 | ||
886 | i8042_ctr = i8042_initial_ctr; | ||
887 | if (i8042_direct) | ||
888 | i8042_ctr &= ~I8042_CTR_XLATE; | ||
892 | i8042_ctr |= I8042_CTR_AUXDIS | I8042_CTR_KBDDIS; | 889 | i8042_ctr |= I8042_CTR_AUXDIS | I8042_CTR_KBDDIS; |
893 | i8042_ctr &= ~(I8042_CTR_AUXINT | I8042_CTR_KBDINT); | 890 | i8042_ctr &= ~(I8042_CTR_AUXINT | I8042_CTR_KBDINT); |
894 | if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) { | 891 | if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) { |
@@ -909,8 +906,11 @@ static int i8042_resume(struct platform_device *dev) | |||
909 | 906 | ||
910 | i8042_interrupt(0, NULL); | 907 | i8042_interrupt(0, NULL); |
911 | 908 | ||
909 | dev->dev.power.power_state = PMSG_ON; | ||
910 | |||
912 | return 0; | 911 | return 0; |
913 | } | 912 | } |
913 | #endif /* CONFIG_PM */ | ||
914 | 914 | ||
915 | /* | 915 | /* |
916 | * We need to reset the 8042 back to original mode on system shutdown, | 916 | * We need to reset the 8042 back to original mode on system shutdown, |
@@ -919,7 +919,7 @@ static int i8042_resume(struct platform_device *dev) | |||
919 | 919 | ||
920 | static void i8042_shutdown(struct platform_device *dev) | 920 | static void i8042_shutdown(struct platform_device *dev) |
921 | { | 921 | { |
922 | i8042_controller_cleanup(); | 922 | i8042_controller_reset(); |
923 | } | 923 | } |
924 | 924 | ||
925 | static int __devinit i8042_create_kbd_port(void) | 925 | static int __devinit i8042_create_kbd_port(void) |
@@ -1154,9 +1154,11 @@ static struct platform_driver i8042_driver = { | |||
1154 | }, | 1154 | }, |
1155 | .probe = i8042_probe, | 1155 | .probe = i8042_probe, |
1156 | .remove = __devexit_p(i8042_remove), | 1156 | .remove = __devexit_p(i8042_remove), |
1157 | .shutdown = i8042_shutdown, | ||
1158 | #ifdef CONFIG_PM | ||
1157 | .suspend = i8042_suspend, | 1159 | .suspend = i8042_suspend, |
1158 | .resume = i8042_resume, | 1160 | .resume = i8042_resume, |
1159 | .shutdown = i8042_shutdown, | 1161 | #endif |
1160 | }; | 1162 | }; |
1161 | 1163 | ||
1162 | static int __init i8042_init(void) | 1164 | static int __init i8042_init(void) |