diff options
author | Rafael J. Wysocki <rjw@rjwysocki.net> | 2015-03-09 20:03:07 -0400 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2015-03-09 20:05:31 -0400 |
commit | f13b2065de8147a1652b830ea5db961cf80c09df (patch) | |
tree | b54de849a839be23fee08b11515786a14f50ce42 | |
parent | 91c68a7c1d92b48287f2f3111a9b09b26a263d3f (diff) |
Input: i8042 - allow KBD and AUX ports to wake up from suspend-to-idle
While registering serio device for i8042, mark them as wakeup-capable
and check their user space wakeup settings in i8042_pm_suspend() and
i8042_pm_resume() to enable or disable, respectively, their interrupts
to wake up the system.
This makes it possible to use the PC keyboard to wake up the system
from suspend-to-idle, among other things, after writing "enabled" to
the keyboard serio device's power/wakeup sysfs attribute.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
-rw-r--r-- | drivers/input/serio/i8042.c | 28 |
1 files changed, 25 insertions, 3 deletions
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c index 986a71c614b0..cb5ece77fd7d 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c | |||
@@ -1162,13 +1162,32 @@ static int i8042_controller_resume(bool force_reset) | |||
1162 | 1162 | ||
1163 | static int i8042_pm_suspend(struct device *dev) | 1163 | static int i8042_pm_suspend(struct device *dev) |
1164 | { | 1164 | { |
1165 | int i; | ||
1166 | |||
1165 | i8042_controller_reset(true); | 1167 | i8042_controller_reset(true); |
1166 | 1168 | ||
1169 | /* Set up serio interrupts for system wakeup. */ | ||
1170 | for (i = 0; i < I8042_NUM_PORTS; i++) { | ||
1171 | struct serio *serio = i8042_ports[i].serio; | ||
1172 | |||
1173 | if (serio && device_may_wakeup(&serio->dev)) | ||
1174 | enable_irq_wake(i8042_ports[i].irq); | ||
1175 | } | ||
1176 | |||
1167 | return 0; | 1177 | return 0; |
1168 | } | 1178 | } |
1169 | 1179 | ||
1170 | static int i8042_pm_resume(struct device *dev) | 1180 | static int i8042_pm_resume(struct device *dev) |
1171 | { | 1181 | { |
1182 | int i; | ||
1183 | |||
1184 | for (i = 0; i < I8042_NUM_PORTS; i++) { | ||
1185 | struct serio *serio = i8042_ports[i].serio; | ||
1186 | |||
1187 | if (serio && device_may_wakeup(&serio->dev)) | ||
1188 | disable_irq_wake(i8042_ports[i].irq); | ||
1189 | } | ||
1190 | |||
1172 | /* | 1191 | /* |
1173 | * On resume from S2R we always try to reset the controller | 1192 | * On resume from S2R we always try to reset the controller |
1174 | * to bring it in a sane state. (In case of S2D we expect | 1193 | * to bring it in a sane state. (In case of S2D we expect |
@@ -1300,13 +1319,16 @@ static void __init i8042_register_ports(void) | |||
1300 | int i; | 1319 | int i; |
1301 | 1320 | ||
1302 | for (i = 0; i < I8042_NUM_PORTS; i++) { | 1321 | for (i = 0; i < I8042_NUM_PORTS; i++) { |
1303 | if (i8042_ports[i].serio) { | 1322 | struct serio *serio = i8042_ports[i].serio; |
1323 | |||
1324 | if (serio) { | ||
1304 | printk(KERN_INFO "serio: %s at %#lx,%#lx irq %d\n", | 1325 | printk(KERN_INFO "serio: %s at %#lx,%#lx irq %d\n", |
1305 | i8042_ports[i].serio->name, | 1326 | serio->name, |
1306 | (unsigned long) I8042_DATA_REG, | 1327 | (unsigned long) I8042_DATA_REG, |
1307 | (unsigned long) I8042_COMMAND_REG, | 1328 | (unsigned long) I8042_COMMAND_REG, |
1308 | i8042_ports[i].irq); | 1329 | i8042_ports[i].irq); |
1309 | serio_register_port(i8042_ports[i].serio); | 1330 | serio_register_port(serio); |
1331 | device_set_wakeup_capable(&serio->dev, true); | ||
1310 | } | 1332 | } |
1311 | } | 1333 | } |
1312 | } | 1334 | } |