diff options
author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2011-10-29 15:37:06 -0400 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2011-11-05 03:01:56 -0400 |
commit | 1729ad1f4f9e167ade84ca8b5269695c42351160 (patch) | |
tree | 361bf91a7f300574a0ab064f2b8847f02bb26be4 | |
parent | fb6c721b69d4ac518b9be6de8f44ba87a0c0d235 (diff) |
Input: i8042 - also perform controller reset when suspending
In addition to some laptops needing i8042 reset after resuming from S2R to
get their touchpads working there is another class of laptops - ones that
need i8042 reset before going to S2R, otherwise they will simply reboot
instead of resuming.
See https://bugzilla.kernel.org/show_bug.cgi?id=15612
This change forces reset of i8042 before doing S2R.
Reported-by: Stefan Koch <stefan_koch@gmx.net>
Tested-by: Alexander van Loon <a.vanloon@alexandervanloon.nl>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
-rw-r--r-- | drivers/input/serio/i8042.c | 23 |
1 files changed, 15 insertions, 8 deletions
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c index d37a48e099d0..86564414b75a 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c | |||
@@ -991,7 +991,7 @@ static int i8042_controller_init(void) | |||
991 | * Reset the controller and reset CRT to the original value set by BIOS. | 991 | * Reset the controller and reset CRT to the original value set by BIOS. |
992 | */ | 992 | */ |
993 | 993 | ||
994 | static void i8042_controller_reset(void) | 994 | static void i8042_controller_reset(bool force_reset) |
995 | { | 995 | { |
996 | i8042_flush(); | 996 | i8042_flush(); |
997 | 997 | ||
@@ -1016,7 +1016,7 @@ static void i8042_controller_reset(void) | |||
1016 | * Reset the controller if requested. | 1016 | * Reset the controller if requested. |
1017 | */ | 1017 | */ |
1018 | 1018 | ||
1019 | if (i8042_reset) | 1019 | if (i8042_reset || force_reset) |
1020 | i8042_controller_selftest(); | 1020 | i8042_controller_selftest(); |
1021 | 1021 | ||
1022 | /* | 1022 | /* |
@@ -1139,9 +1139,9 @@ static int i8042_controller_resume(bool force_reset) | |||
1139 | * upsetting it. | 1139 | * upsetting it. |
1140 | */ | 1140 | */ |
1141 | 1141 | ||
1142 | static int i8042_pm_reset(struct device *dev) | 1142 | static int i8042_pm_suspend(struct device *dev) |
1143 | { | 1143 | { |
1144 | i8042_controller_reset(); | 1144 | i8042_controller_reset(true); |
1145 | 1145 | ||
1146 | return 0; | 1146 | return 0; |
1147 | } | 1147 | } |
@@ -1163,13 +1163,20 @@ static int i8042_pm_thaw(struct device *dev) | |||
1163 | return 0; | 1163 | return 0; |
1164 | } | 1164 | } |
1165 | 1165 | ||
1166 | static int i8042_pm_reset(struct device *dev) | ||
1167 | { | ||
1168 | i8042_controller_reset(false); | ||
1169 | |||
1170 | return 0; | ||
1171 | } | ||
1172 | |||
1166 | static int i8042_pm_restore(struct device *dev) | 1173 | static int i8042_pm_restore(struct device *dev) |
1167 | { | 1174 | { |
1168 | return i8042_controller_resume(false); | 1175 | return i8042_controller_resume(false); |
1169 | } | 1176 | } |
1170 | 1177 | ||
1171 | static const struct dev_pm_ops i8042_pm_ops = { | 1178 | static const struct dev_pm_ops i8042_pm_ops = { |
1172 | .suspend = i8042_pm_reset, | 1179 | .suspend = i8042_pm_suspend, |
1173 | .resume = i8042_pm_resume, | 1180 | .resume = i8042_pm_resume, |
1174 | .thaw = i8042_pm_thaw, | 1181 | .thaw = i8042_pm_thaw, |
1175 | .poweroff = i8042_pm_reset, | 1182 | .poweroff = i8042_pm_reset, |
@@ -1185,7 +1192,7 @@ static const struct dev_pm_ops i8042_pm_ops = { | |||
1185 | 1192 | ||
1186 | static void i8042_shutdown(struct platform_device *dev) | 1193 | static void i8042_shutdown(struct platform_device *dev) |
1187 | { | 1194 | { |
1188 | i8042_controller_reset(); | 1195 | i8042_controller_reset(false); |
1189 | } | 1196 | } |
1190 | 1197 | ||
1191 | static int __init i8042_create_kbd_port(void) | 1198 | static int __init i8042_create_kbd_port(void) |
@@ -1424,7 +1431,7 @@ static int __init i8042_probe(struct platform_device *dev) | |||
1424 | out_fail: | 1431 | out_fail: |
1425 | i8042_free_aux_ports(); /* in case KBD failed but AUX not */ | 1432 | i8042_free_aux_ports(); /* in case KBD failed but AUX not */ |
1426 | i8042_free_irqs(); | 1433 | i8042_free_irqs(); |
1427 | i8042_controller_reset(); | 1434 | i8042_controller_reset(false); |
1428 | i8042_platform_device = NULL; | 1435 | i8042_platform_device = NULL; |
1429 | 1436 | ||
1430 | return error; | 1437 | return error; |
@@ -1434,7 +1441,7 @@ static int __devexit i8042_remove(struct platform_device *dev) | |||
1434 | { | 1441 | { |
1435 | i8042_unregister_ports(); | 1442 | i8042_unregister_ports(); |
1436 | i8042_free_irqs(); | 1443 | i8042_free_irqs(); |
1437 | i8042_controller_reset(); | 1444 | i8042_controller_reset(false); |
1438 | i8042_platform_device = NULL; | 1445 | i8042_platform_device = NULL; |
1439 | 1446 | ||
1440 | return 0; | 1447 | return 0; |