diff options
Diffstat (limited to 'drivers/input/serio/i8042.c')
-rw-r--r-- | drivers/input/serio/i8042.c | 68 |
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) |