Skip to content

Commit 684bec1

Browse files
dsddtor
authored andcommitted
Input: i8042 - enable keyboard wakeups by default when s2idle is used
Previously, on typical consumer laptops, pressing a key on the keyboard when the system is in suspend would cause it to wake up (default or unconditional behaviour). This happens because the EC generates a SCI interrupt in this scenario. That is no longer true on modern laptops based on Intel WhiskeyLake, including Acer Swift SF314-55G, Asus UX333FA, Asus UX433FN and Asus UX533FD. We confirmed with Asus EC engineers that the "Modern Standby" design has been modified so that the EC no longer generates a SCI in this case; the keyboard controller itself should be used for wakeup. In order to retain the standard behaviour of being able to use the keyboard to wake up the system, enable serio wakeups by default on platforms that are using s2idle. Link: https://lkml.kernel.org/r/CAB4CAwfQ0mPMqCLp95TVjw4J0r5zKPWkSvvkK4cpZUGE--w8bQ@mail.gmail.com Reviewed-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Signed-off-by: Daniel Drake <drake@endlessm.com> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
1 parent 9735082 commit 684bec1

File tree

3 files changed

+28
-9
lines changed

3 files changed

+28
-9
lines changed

drivers/input/serio/i8042.c

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1395,15 +1395,26 @@ static void __init i8042_register_ports(void)
13951395
for (i = 0; i < I8042_NUM_PORTS; i++) {
13961396
struct serio *serio = i8042_ports[i].serio;
13971397

1398-
if (serio) {
1399-
printk(KERN_INFO "serio: %s at %#lx,%#lx irq %d\n",
1400-
serio->name,
1401-
(unsigned long) I8042_DATA_REG,
1402-
(unsigned long) I8042_COMMAND_REG,
1403-
i8042_ports[i].irq);
1404-
serio_register_port(serio);
1405-
device_set_wakeup_capable(&serio->dev, true);
1406-
}
1398+
if (!serio)
1399+
continue;
1400+
1401+
printk(KERN_INFO "serio: %s at %#lx,%#lx irq %d\n",
1402+
serio->name,
1403+
(unsigned long) I8042_DATA_REG,
1404+
(unsigned long) I8042_COMMAND_REG,
1405+
i8042_ports[i].irq);
1406+
serio_register_port(serio);
1407+
device_set_wakeup_capable(&serio->dev, true);
1408+
1409+
/*
1410+
* On platforms using suspend-to-idle, allow the keyboard to
1411+
* wake up the system from sleep by enabling keyboard wakeups
1412+
* by default. This is consistent with keyboard wakeup
1413+
* behavior on many platforms using suspend-to-RAM (ACPI S3)
1414+
* by default.
1415+
*/
1416+
if (pm_suspend_via_s2idle() && i == I8042_KBD_PORT_NO)
1417+
device_set_wakeup_enable(&serio->dev, true);
14071418
}
14081419
}
14091420

include/linux/suspend.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,7 @@ static inline bool idle_should_enter_s2idle(void)
251251
return unlikely(s2idle_state == S2IDLE_STATE_ENTER);
252252
}
253253

254+
extern bool pm_suspend_via_s2idle(void);
254255
extern void __init pm_states_init(void);
255256
extern void s2idle_set_ops(const struct platform_s2idle_ops *ops);
256257
extern void s2idle_wake(void);
@@ -282,6 +283,7 @@ static inline void pm_set_suspend_via_firmware(void) {}
282283
static inline void pm_set_resume_via_firmware(void) {}
283284
static inline bool pm_suspend_via_firmware(void) { return false; }
284285
static inline bool pm_resume_via_firmware(void) { return false; }
286+
static inline bool pm_suspend_via_s2idle(void) { return false; }
285287

286288
static inline void suspend_set_ops(const struct platform_suspend_ops *ops) {}
287289
static inline int pm_suspend(suspend_state_t state) { return -ENOSYS; }

kernel/power/suspend.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,12 @@ static DECLARE_WAIT_QUEUE_HEAD(s2idle_wait_head);
6262
enum s2idle_states __read_mostly s2idle_state;
6363
static DEFINE_SPINLOCK(s2idle_lock);
6464

65+
bool pm_suspend_via_s2idle(void)
66+
{
67+
return mem_sleep_current == PM_SUSPEND_TO_IDLE;
68+
}
69+
EXPORT_SYMBOL_GPL(pm_suspend_via_s2idle);
70+
6571
void s2idle_set_ops(const struct platform_s2idle_ops *ops)
6672
{
6773
lock_system_sleep();

0 commit comments

Comments
 (0)