diff options
Diffstat (limited to 'drivers/input/serio/i8042.c')
-rw-r--r-- | drivers/input/serio/i8042.c | 90 |
1 files changed, 46 insertions, 44 deletions
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c index 6440a8f55686..46e4ba0b9246 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c | |||
@@ -61,10 +61,6 @@ static bool i8042_noloop; | |||
61 | module_param_named(noloop, i8042_noloop, bool, 0); | 61 | module_param_named(noloop, i8042_noloop, bool, 0); |
62 | MODULE_PARM_DESC(noloop, "Disable the AUX Loopback command while probing for the AUX port"); | 62 | MODULE_PARM_DESC(noloop, "Disable the AUX Loopback command while probing for the AUX port"); |
63 | 63 | ||
64 | static unsigned int i8042_blink_frequency = 500; | ||
65 | module_param_named(panicblink, i8042_blink_frequency, uint, 0600); | ||
66 | MODULE_PARM_DESC(panicblink, "Frequency with which keyboard LEDs should blink when kernel panics"); | ||
67 | |||
68 | #ifdef CONFIG_X86 | 64 | #ifdef CONFIG_X86 |
69 | static bool i8042_dritek; | 65 | static bool i8042_dritek; |
70 | module_param_named(dritek, i8042_dritek, bool, 0); | 66 | module_param_named(dritek, i8042_dritek, bool, 0); |
@@ -861,9 +857,6 @@ static int i8042_controller_selftest(void) | |||
861 | unsigned char param; | 857 | unsigned char param; |
862 | int i = 0; | 858 | int i = 0; |
863 | 859 | ||
864 | if (!i8042_reset) | ||
865 | return 0; | ||
866 | |||
867 | /* | 860 | /* |
868 | * We try this 5 times; on some really fragile systems this does not | 861 | * We try this 5 times; on some really fragile systems this does not |
869 | * take the first time... | 862 | * take the first time... |
@@ -1020,7 +1013,8 @@ static void i8042_controller_reset(void) | |||
1020 | * Reset the controller if requested. | 1013 | * Reset the controller if requested. |
1021 | */ | 1014 | */ |
1022 | 1015 | ||
1023 | i8042_controller_selftest(); | 1016 | if (i8042_reset) |
1017 | i8042_controller_selftest(); | ||
1024 | 1018 | ||
1025 | /* | 1019 | /* |
1026 | * Restore the original control register setting. | 1020 | * Restore the original control register setting. |
@@ -1032,8 +1026,8 @@ static void i8042_controller_reset(void) | |||
1032 | 1026 | ||
1033 | 1027 | ||
1034 | /* | 1028 | /* |
1035 | * i8042_panic_blink() will flash the keyboard LEDs and is called when | 1029 | * i8042_panic_blink() will turn the keyboard LEDs on or off and is called |
1036 | * kernel panics. Flashing LEDs is useful for users running X who may | 1030 | * when kernel panics. Flashing LEDs is useful for users running X who may |
1037 | * not see the console and will help distingushing panics from "real" | 1031 | * not see the console and will help distingushing panics from "real" |
1038 | * lockups. | 1032 | * lockups. |
1039 | * | 1033 | * |
@@ -1043,22 +1037,12 @@ static void i8042_controller_reset(void) | |||
1043 | 1037 | ||
1044 | #define DELAY do { mdelay(1); if (++delay > 10) return delay; } while(0) | 1038 | #define DELAY do { mdelay(1); if (++delay > 10) return delay; } while(0) |
1045 | 1039 | ||
1046 | static long i8042_panic_blink(long count) | 1040 | static long i8042_panic_blink(int state) |
1047 | { | 1041 | { |
1048 | long delay = 0; | 1042 | long delay = 0; |
1049 | static long last_blink; | 1043 | char led; |
1050 | static char led; | ||
1051 | 1044 | ||
1052 | /* | 1045 | led = (state) ? 0x01 | 0x04 : 0; |
1053 | * We expect frequency to be about 1/2s. KDB uses about 1s. | ||
1054 | * Make sure they are different. | ||
1055 | */ | ||
1056 | if (!i8042_blink_frequency) | ||
1057 | return 0; | ||
1058 | if (count - last_blink < i8042_blink_frequency) | ||
1059 | return 0; | ||
1060 | |||
1061 | led ^= 0x01 | 0x04; | ||
1062 | while (i8042_read_status() & I8042_STR_IBF) | 1046 | while (i8042_read_status() & I8042_STR_IBF) |
1063 | DELAY; | 1047 | DELAY; |
1064 | dbg("%02x -> i8042 (panic blink)", 0xed); | 1048 | dbg("%02x -> i8042 (panic blink)", 0xed); |
@@ -1071,7 +1055,6 @@ static long i8042_panic_blink(long count) | |||
1071 | dbg("%02x -> i8042 (panic blink)", led); | 1055 | dbg("%02x -> i8042 (panic blink)", led); |
1072 | i8042_write_data(led); | 1056 | i8042_write_data(led); |
1073 | DELAY; | 1057 | DELAY; |
1074 | last_blink = count; | ||
1075 | return delay; | 1058 | return delay; |
1076 | } | 1059 | } |
1077 | 1060 | ||
@@ -1094,23 +1077,11 @@ static void i8042_dritek_enable(void) | |||
1094 | #ifdef CONFIG_PM | 1077 | #ifdef CONFIG_PM |
1095 | 1078 | ||
1096 | /* | 1079 | /* |
1097 | * Here we try to restore the original BIOS settings to avoid | ||
1098 | * upsetting it. | ||
1099 | */ | ||
1100 | |||
1101 | static int i8042_pm_reset(struct device *dev) | ||
1102 | { | ||
1103 | i8042_controller_reset(); | ||
1104 | |||
1105 | return 0; | ||
1106 | } | ||
1107 | |||
1108 | /* | ||
1109 | * Here we try to reset everything back to a state we had | 1080 | * Here we try to reset everything back to a state we had |
1110 | * before suspending. | 1081 | * before suspending. |
1111 | */ | 1082 | */ |
1112 | 1083 | ||
1113 | static int i8042_pm_restore(struct device *dev) | 1084 | static int i8042_controller_resume(bool force_reset) |
1114 | { | 1085 | { |
1115 | int error; | 1086 | int error; |
1116 | 1087 | ||
@@ -1118,9 +1089,11 @@ static int i8042_pm_restore(struct device *dev) | |||
1118 | if (error) | 1089 | if (error) |
1119 | return error; | 1090 | return error; |
1120 | 1091 | ||
1121 | error = i8042_controller_selftest(); | 1092 | if (i8042_reset || force_reset) { |
1122 | if (error) | 1093 | error = i8042_controller_selftest(); |
1123 | return error; | 1094 | if (error) |
1095 | return error; | ||
1096 | } | ||
1124 | 1097 | ||
1125 | /* | 1098 | /* |
1126 | * Restore original CTR value and disable all ports | 1099 | * Restore original CTR value and disable all ports |
@@ -1162,6 +1135,28 @@ static int i8042_pm_restore(struct device *dev) | |||
1162 | return 0; | 1135 | return 0; |
1163 | } | 1136 | } |
1164 | 1137 | ||
1138 | /* | ||
1139 | * Here we try to restore the original BIOS settings to avoid | ||
1140 | * upsetting it. | ||
1141 | */ | ||
1142 | |||
1143 | static int i8042_pm_reset(struct device *dev) | ||
1144 | { | ||
1145 | i8042_controller_reset(); | ||
1146 | |||
1147 | return 0; | ||
1148 | } | ||
1149 | |||
1150 | static int i8042_pm_resume(struct device *dev) | ||
1151 | { | ||
1152 | /* | ||
1153 | * On resume from S2R we always try to reset the controller | ||
1154 | * to bring it in a sane state. (In case of S2D we expect | ||
1155 | * BIOS to reset the controller for us.) | ||
1156 | */ | ||
1157 | return i8042_controller_resume(true); | ||
1158 | } | ||
1159 | |||
1165 | static int i8042_pm_thaw(struct device *dev) | 1160 | static int i8042_pm_thaw(struct device *dev) |
1166 | { | 1161 | { |
1167 | i8042_interrupt(0, NULL); | 1162 | i8042_interrupt(0, NULL); |
@@ -1169,9 +1164,14 @@ static int i8042_pm_thaw(struct device *dev) | |||
1169 | return 0; | 1164 | return 0; |
1170 | } | 1165 | } |
1171 | 1166 | ||
1167 | static int i8042_pm_restore(struct device *dev) | ||
1168 | { | ||
1169 | return i8042_controller_resume(false); | ||
1170 | } | ||
1171 | |||
1172 | static const struct dev_pm_ops i8042_pm_ops = { | 1172 | static const struct dev_pm_ops i8042_pm_ops = { |
1173 | .suspend = i8042_pm_reset, | 1173 | .suspend = i8042_pm_reset, |
1174 | .resume = i8042_pm_restore, | 1174 | .resume = i8042_pm_resume, |
1175 | .thaw = i8042_pm_thaw, | 1175 | .thaw = i8042_pm_thaw, |
1176 | .poweroff = i8042_pm_reset, | 1176 | .poweroff = i8042_pm_reset, |
1177 | .restore = i8042_pm_restore, | 1177 | .restore = i8042_pm_restore, |
@@ -1389,9 +1389,11 @@ static int __init i8042_probe(struct platform_device *dev) | |||
1389 | 1389 | ||
1390 | i8042_platform_device = dev; | 1390 | i8042_platform_device = dev; |
1391 | 1391 | ||
1392 | error = i8042_controller_selftest(); | 1392 | if (i8042_reset) { |
1393 | if (error) | 1393 | error = i8042_controller_selftest(); |
1394 | return error; | 1394 | if (error) |
1395 | return error; | ||
1396 | } | ||
1395 | 1397 | ||
1396 | error = i8042_controller_init(); | 1398 | error = i8042_controller_init(); |
1397 | if (error) | 1399 | if (error) |