aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2010-07-20 23:25:34 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2010-07-20 23:32:21 -0400
commit1ca56e513a9fd356d5a9e0de45dbe0e189e00386 (patch)
treee260d6d14f188ac6a0269e66986abbdb231f715d /drivers/input
parent58fb021827b7455e05d89371556e6c255e9fb2e1 (diff)
Input: i8042 - reset keyboard controller wehen resuming from S2R
Some laptops, such as Lenovo 3000 N100, require keyboard controller reset in order to have touchpad operable after suspend to RAM. Even if box does not need the reset it should be safe to do so, so instead of chasing after misbehaving boxes and grow DMI tables, let's reset the controller unconditionally. Reported-and-tested-by: Jerome Lacoste <jerome.lacoste@gmail.com> Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input')
-rw-r--r--drivers/input/serio/i8042.c65
1 files changed, 41 insertions, 24 deletions
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
index 6440a8f55686..258b98b9d7c2 100644
--- a/drivers/input/serio/i8042.c
+++ b/drivers/input/serio/i8042.c
@@ -861,9 +861,6 @@ static int i8042_controller_selftest(void)
861 unsigned char param; 861 unsigned char param;
862 int i = 0; 862 int i = 0;
863 863
864 if (!i8042_reset)
865 return 0;
866
867 /* 864 /*
868 * We try this 5 times; on some really fragile systems this does not 865 * We try this 5 times; on some really fragile systems this does not
869 * take the first time... 866 * take the first time...
@@ -1020,7 +1017,8 @@ static void i8042_controller_reset(void)
1020 * Reset the controller if requested. 1017 * Reset the controller if requested.
1021 */ 1018 */
1022 1019
1023 i8042_controller_selftest(); 1020 if (i8042_reset)
1021 i8042_controller_selftest();
1024 1022
1025/* 1023/*
1026 * Restore the original control register setting. 1024 * Restore the original control register setting.
@@ -1094,23 +1092,11 @@ static void i8042_dritek_enable(void)
1094#ifdef CONFIG_PM 1092#ifdef CONFIG_PM
1095 1093
1096/* 1094/*
1097 * Here we try to restore the original BIOS settings to avoid
1098 * upsetting it.
1099 */
1100
1101static 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 1095 * Here we try to reset everything back to a state we had
1110 * before suspending. 1096 * before suspending.
1111 */ 1097 */
1112 1098
1113static int i8042_pm_restore(struct device *dev) 1099static int i8042_controller_resume(bool force_reset)
1114{ 1100{
1115 int error; 1101 int error;
1116 1102
@@ -1118,9 +1104,11 @@ static int i8042_pm_restore(struct device *dev)
1118 if (error) 1104 if (error)
1119 return error; 1105 return error;
1120 1106
1121 error = i8042_controller_selftest(); 1107 if (i8042_reset || force_reset) {
1122 if (error) 1108 error = i8042_controller_selftest();
1123 return error; 1109 if (error)
1110 return error;
1111 }
1124 1112
1125/* 1113/*
1126 * Restore original CTR value and disable all ports 1114 * Restore original CTR value and disable all ports
@@ -1162,6 +1150,28 @@ static int i8042_pm_restore(struct device *dev)
1162 return 0; 1150 return 0;
1163} 1151}
1164 1152
1153/*
1154 * Here we try to restore the original BIOS settings to avoid
1155 * upsetting it.
1156 */
1157
1158static int i8042_pm_reset(struct device *dev)
1159{
1160 i8042_controller_reset();
1161
1162 return 0;
1163}
1164
1165static int i8042_pm_resume(struct device *dev)
1166{
1167 /*
1168 * On resume from S2R we always try to reset the controller
1169 * to bring it in a sane state. (In case of S2D we expect
1170 * BIOS to reset the controller for us.)
1171 */
1172 return i8042_controller_resume(true);
1173}
1174
1165static int i8042_pm_thaw(struct device *dev) 1175static int i8042_pm_thaw(struct device *dev)
1166{ 1176{
1167 i8042_interrupt(0, NULL); 1177 i8042_interrupt(0, NULL);
@@ -1169,9 +1179,14 @@ static int i8042_pm_thaw(struct device *dev)
1169 return 0; 1179 return 0;
1170} 1180}
1171 1181
1182static int i8042_pm_restore(struct device *dev)
1183{
1184 return i8042_controller_resume(false);
1185}
1186
1172static const struct dev_pm_ops i8042_pm_ops = { 1187static const struct dev_pm_ops i8042_pm_ops = {
1173 .suspend = i8042_pm_reset, 1188 .suspend = i8042_pm_reset,
1174 .resume = i8042_pm_restore, 1189 .resume = i8042_pm_resume,
1175 .thaw = i8042_pm_thaw, 1190 .thaw = i8042_pm_thaw,
1176 .poweroff = i8042_pm_reset, 1191 .poweroff = i8042_pm_reset,
1177 .restore = i8042_pm_restore, 1192 .restore = i8042_pm_restore,
@@ -1389,9 +1404,11 @@ static int __init i8042_probe(struct platform_device *dev)
1389 1404
1390 i8042_platform_device = dev; 1405 i8042_platform_device = dev;
1391 1406
1392 error = i8042_controller_selftest(); 1407 if (i8042_reset) {
1393 if (error) 1408 error = i8042_controller_selftest();
1394 return error; 1409 if (error)
1410 return error;
1411 }
1395 1412
1396 error = i8042_controller_init(); 1413 error = i8042_controller_init();
1397 if (error) 1414 if (error)