aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2015-11-02 00:52:19 +0100
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2015-11-02 00:52:19 +0100
commit9bb4064ca3bd771f8df88529a3578f9bb5243911 (patch)
treea148f0ff6ee2f5bb6d556ac7a39e30311862eafd /drivers/input
parentMerge branches 'acpi-osl', 'acpi-pad', 'acpi-video' and 'acpi-assorted' (diff)
parentPM / hibernate: fix a comment typo (diff)
downloadlinux-dev-9bb4064ca3bd771f8df88529a3578f9bb5243911.tar.xz
linux-dev-9bb4064ca3bd771f8df88529a3578f9bb5243911.zip
Merge branch 'pm-sleep'
* pm-sleep: PM / hibernate: fix a comment typo input: i8042: Avoid resetting controller on system suspend/resume PM / PCI / ACPI: Kick devices that might have been reset by firmware PM / sleep: Add flags to indicate platform firmware involvement PM / sleep: Drop pm_request_idle() from pm_generic_complete() PCI / PM: Avoid resuming more devices during system suspend PM / wakeup: wakeup_source_create: use kstrdup_const PM / sleep: Report interrupt that caused system wakeup
Diffstat (limited to 'drivers/input')
-rw-r--r--drivers/input/serio/i8042.c32
1 files changed, 27 insertions, 5 deletions
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
index db91de539ee3..454195709a82 100644
--- a/drivers/input/serio/i8042.c
+++ b/drivers/input/serio/i8042.c
@@ -24,6 +24,7 @@
#include <linux/platform_device.h>
#include <linux/i8042.h>
#include <linux/slab.h>
+#include <linux/suspend.h>
#include <asm/io.h>
@@ -1170,7 +1171,8 @@ static int i8042_pm_suspend(struct device *dev)
{
int i;
- i8042_controller_reset(true);
+ if (pm_suspend_via_firmware())
+ i8042_controller_reset(true);
/* Set up serio interrupts for system wakeup. */
for (i = 0; i < I8042_NUM_PORTS; i++) {
@@ -1183,8 +1185,17 @@ static int i8042_pm_suspend(struct device *dev)
return 0;
}
+static int i8042_pm_resume_noirq(struct device *dev)
+{
+ if (!pm_resume_via_firmware())
+ i8042_interrupt(0, NULL);
+
+ return 0;
+}
+
static int i8042_pm_resume(struct device *dev)
{
+ bool force_reset;
int i;
for (i = 0; i < I8042_NUM_PORTS; i++) {
@@ -1195,11 +1206,21 @@ 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.)
+ * If platform firmware was not going to be involved in suspend, we did
+ * not restore the controller state to whatever it had been at boot
+ * time, so we do not need to do anything.
*/
- return i8042_controller_resume(true);
+ if (!pm_suspend_via_firmware())
+ return 0;
+
+ /*
+ * We only need to reset the controller if we are resuming after handing
+ * off control to the platform firmware, otherwise we can simply restore
+ * the mode.
+ */
+ force_reset = pm_resume_via_firmware();
+
+ return i8042_controller_resume(force_reset);
}
static int i8042_pm_thaw(struct device *dev)
@@ -1223,6 +1244,7 @@ static int i8042_pm_restore(struct device *dev)
static const struct dev_pm_ops i8042_pm_ops = {
.suspend = i8042_pm_suspend,
+ .resume_noirq = i8042_pm_resume_noirq,
.resume = i8042_pm_resume,
.thaw = i8042_pm_thaw,
.poweroff = i8042_pm_reset,