summaryrefslogtreecommitdiffstats
path: root/drivers/input/serio/i8042.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/serio/i8042.c')
-rw-r--r--drivers/input/serio/i8042.c68
1 files changed, 43 insertions, 25 deletions
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
index 9302ba0e48f..258b98b9d7c 100644
--- a/drivers/input/serio/i8042.c
+++ b/drivers/input/serio/i8042.c
@@ -21,6 +21,7 @@
#include <linux/rcupdate.h>
#include <linux/platform_device.h>
#include <linux/i8042.h>
+#include <linux/slab.h>
#include <asm/io.h>
@@ -38,7 +39,7 @@ MODULE_PARM_DESC(noaux, "Do not probe or use AUX (mouse) port.");
static bool i8042_nomux;
module_param_named(nomux, i8042_nomux, bool, 0);
-MODULE_PARM_DESC(nomux, "Do not check whether an active multiplexing conrtoller is present.");
+MODULE_PARM_DESC(nomux, "Do not check whether an active multiplexing controller is present.");
static bool i8042_unlock;
module_param_named(unlock, i8042_unlock, bool, 0);
@@ -860,9 +861,6 @@ static int i8042_controller_selftest(void)
unsigned char param;
int i = 0;
- if (!i8042_reset)
- return 0;
-
/*
* We try this 5 times; on some really fragile systems this does not
* take the first time...
@@ -1019,7 +1017,8 @@ static void i8042_controller_reset(void)
* Reset the controller if requested.
*/
- i8042_controller_selftest();
+ if (i8042_reset)
+ i8042_controller_selftest();
/*
* Restore the original control register setting.
@@ -1093,23 +1092,11 @@ static void i8042_dritek_enable(void)
#ifdef CONFIG_PM
/*
- * Here we try to restore the original BIOS settings to avoid
- * upsetting it.
- */
-
-static int i8042_pm_reset(struct device *dev)
-{
- i8042_controller_reset();
-
- return 0;
-}
-
-/*
* Here we try to reset everything back to a state we had
* before suspending.
*/
-static int i8042_pm_restore(struct device *dev)
+static int i8042_controller_resume(bool force_reset)
{
int error;
@@ -1117,9 +1104,11 @@ static int i8042_pm_restore(struct device *dev)
if (error)
return error;
- error = i8042_controller_selftest();
- if (error)
- return error;
+ if (i8042_reset || force_reset) {
+ error = i8042_controller_selftest();
+ if (error)
+ return error;
+ }
/*
* Restore original CTR value and disable all ports
@@ -1161,6 +1150,28 @@ static int i8042_pm_restore(struct device *dev)
return 0;
}
+/*
+ * Here we try to restore the original BIOS settings to avoid
+ * upsetting it.
+ */
+
+static int i8042_pm_reset(struct device *dev)
+{
+ i8042_controller_reset();
+
+ return 0;
+}
+
+static int i8042_pm_resume(struct device *dev)
+{
+ /*
+ * On resume from S2R we always try to reset the controller
+ * to bring it in a sane state. (In case of S2D we expect
+ * BIOS to reset the controller for us.)
+ */
+ return i8042_controller_resume(true);
+}
+
static int i8042_pm_thaw(struct device *dev)
{
i8042_interrupt(0, NULL);
@@ -1168,9 +1179,14 @@ static int i8042_pm_thaw(struct device *dev)
return 0;
}
+static int i8042_pm_restore(struct device *dev)
+{
+ return i8042_controller_resume(false);
+}
+
static const struct dev_pm_ops i8042_pm_ops = {
.suspend = i8042_pm_reset,
- .resume = i8042_pm_restore,
+ .resume = i8042_pm_resume,
.thaw = i8042_pm_thaw,
.poweroff = i8042_pm_reset,
.restore = i8042_pm_restore,
@@ -1388,9 +1404,11 @@ static int __init i8042_probe(struct platform_device *dev)
i8042_platform_device = dev;
- error = i8042_controller_selftest();
- if (error)
- return error;
+ if (i8042_reset) {
+ error = i8042_controller_selftest();
+ if (error)
+ return error;
+ }
error = i8042_controller_init();
if (error)