Re: [PATCH] ACPI: button: Report wakeup key only for power button wakeups
"Rafael J. Wysocki (Intel)" <[email protected]> Fri, 7 Aug 2026 16:12:31 +0200
| Newsgroups | gmane.linux.kernel,gmane.linux.acpi.devel |
|---|---|
| Message-ID | <CAJZ5v0gY8TZUDfAvj7WPfVJNyY0PXOEVO1SOSUpuZXV87mpoJA@mail.gmail.com> |
On Thu, Aug 6, 2026 at 2:28 PM Baorui Liu <[email protected]> wrote: > > Commit 16f70feaabe9 ("ACPI: button: trigger wakeup key events") > makes the ACPI power button driver report KEY_WAKEUP from its resume > callback. However, that callback is run whenever the ACPI button device > is resumed, regardless of the actual system wakeup source. > > As a result, userspace may receive a KEY_WAKEUP event after resumes > caused by unrelated wakeup sources. So why is this a problem in practice? > Avoid reporting the input event from acpi_button_resume(). Instead, > report it only when the ACPI fixed power button status indicates that > the power button was the wakeup source. But power buttons need not be fixed event devices and there are also sleep buttons that can generate KEY_WAKEUP, and what about lids? > Fixes: 16f70feaabe9 ("ACPI: button: trigger wakeup key events") > Signed-off-by: Baorui Liu <[email protected]> > --- > drivers/acpi/button.c | 23 +++++++++++++++-------- > drivers/acpi/sleep.c | 21 +++++++++++++++++++++ > drivers/acpi/sleep.h | 1 + > drivers/acpi/x86/s2idle.c | 4 +++- > include/acpi/button.h | 5 +++++ > 5 files changed, 45 insertions(+), 9 deletions(-) > > diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c > index 3836ee75dd66..700510f6e5d0 100644 > --- a/drivers/acpi/button.c > +++ b/drivers/acpi/button.c > @@ -480,6 +480,21 @@ static void acpi_button_notify(acpi_handle handle, u32 event, void *data) > event, ++button->pushed); > } > > +void acpi_power_button_wakeup(struct acpi_device *device) > +{ > + struct acpi_button *button = acpi_driver_data(device); > + struct input_dev *input; > + > + if (button->type == ACPI_BUTTON_TYPE_POWER) { > + input = button->input; > + input_report_key(input, KEY_WAKEUP, 1); > + input_sync(input); > + input_report_key(input, KEY_WAKEUP, 0); > + input_sync(input); > + } > +} > +EXPORT_SYMBOL(acpi_power_button_wakeup); > + > static void acpi_button_notify_run(void *data) > { > acpi_button_notify(NULL, ACPI_BUTTON_NOTIFY_STATUS, data); > @@ -503,7 +518,6 @@ static int acpi_button_suspend(struct device *dev) > static int acpi_button_resume(struct device *dev) > { > struct acpi_button *button = dev_get_drvdata(dev); > - struct input_dev *input; > > button->suspended = false; > if (button->type == ACPI_BUTTON_TYPE_LID) { > @@ -512,13 +526,6 @@ static int acpi_button_resume(struct device *dev) > acpi_lid_initialize_state(button); > } > > - if (button->type == ACPI_BUTTON_TYPE_POWER) { > - input = button->input; > - input_report_key(input, KEY_WAKEUP, 1); > - input_sync(input); > - input_report_key(input, KEY_WAKEUP, 0); > - input_sync(input); > - } > return 0; > } > #endif > diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c > index 132a9df98471..26bbecd0c166 100644 > --- a/drivers/acpi/sleep.c > +++ b/drivers/acpi/sleep.c > @@ -22,6 +22,7 @@ > #include <linux/syscore_ops.h> > #include <asm/io.h> > #include <trace/events/power.h> > +#include <acpi/button.h> > > #include "internal.h" > #include "sleep.h" > @@ -518,6 +519,7 @@ static void acpi_pm_finish(void) > NULL, -1); > if (pwr_btn_adev) { > pm_wakeup_event(&pwr_btn_adev->dev, 0); > + acpi_power_button_wakeup(pwr_btn_adev); > acpi_dev_put(pwr_btn_adev); > } > } > @@ -818,6 +820,24 @@ bool acpi_s2idle_wake(void) > return false; > } > > +void acpi_s2idle_restore_check_powerkey(void) > +{ > + struct acpi_device *pwr_btn_adev; > + acpi_event_status pwr_btn_status = ACPI_EVENT_FLAG_DISABLED; > + > + acpi_get_event_status(ACPI_EVENT_POWER_BUTTON, &pwr_btn_status); > + > + if (pwr_btn_status & ACPI_EVENT_FLAG_STATUS_SET) { > + pwr_btn_adev = acpi_dev_get_first_match_dev(ACPI_BUTTON_HID_POWERF, > + NULL, -1); > + if (pwr_btn_adev) { > + pm_wakeup_event(&pwr_btn_adev->dev, 0); > + acpi_power_button_wakeup(pwr_btn_adev); > + acpi_dev_put(pwr_btn_adev); > + } > + } > +} > + > void acpi_s2idle_restore(void) > { > /* > @@ -849,6 +869,7 @@ static const struct platform_s2idle_ops acpi_s2idle_ops = { > .begin = acpi_s2idle_begin, > .prepare = acpi_s2idle_prepare, > .wake = acpi_s2idle_wake, > + .restore_early = acpi_s2idle_restore_check_powerkey, > .restore = acpi_s2idle_restore, > .end = acpi_s2idle_end, > }; > diff --git a/drivers/acpi/sleep.h b/drivers/acpi/sleep.h > index 9c3cb109c5d2..50382c90446c 100644 > --- a/drivers/acpi/sleep.h > +++ b/drivers/acpi/sleep.h > @@ -18,6 +18,7 @@ static inline acpi_status acpi_set_waking_vector(u32 wakeup_address) > extern int acpi_s2idle_begin(void); > extern int acpi_s2idle_prepare(void); > extern bool acpi_s2idle_wake(void); > +extern void acpi_s2idle_restore_check_powerkey(void); > extern void acpi_s2idle_restore(void); > extern void acpi_s2idle_end(void); > > diff --git a/drivers/acpi/x86/s2idle.c b/drivers/acpi/x86/s2idle.c > index b6b1dd76a06b..ce6663c1ef70 100644 > --- a/drivers/acpi/x86/s2idle.c > +++ b/drivers/acpi/x86/s2idle.c > @@ -598,8 +598,10 @@ static void acpi_s2idle_restore_early_lps0(void) > { > struct acpi_s2idle_dev_ops *handler; > > - if (!lps0_device_handle || sleep_no_lps0) > + if (!lps0_device_handle || sleep_no_lps0) { > + acpi_s2idle_restore_check_powerkey(); > return; > + } > > list_for_each_entry(handler, &lps0_s2idle_devops_head, list_node) > if (handler->restore) > diff --git a/include/acpi/button.h b/include/acpi/button.h > index af2fce5d2ee3..3cbf3272371e 100644 > --- a/include/acpi/button.h > +++ b/include/acpi/button.h > @@ -8,11 +8,16 @@ > > #if IS_ENABLED(CONFIG_ACPI_BUTTON) > extern int acpi_lid_open(void); > +extern void acpi_power_button_wakeup(struct acpi_device *device); > #else > static inline int acpi_lid_open(void) > { > return 1; > } > + > +static inline void acpi_power_button_wakeup(struct acpi_device *device) > +{ > +} > #endif /* IS_ENABLED(CONFIG_ACPI_BUTTON) */ > > #endif /* ACPI_BUTTON_H */ > > base-commit: 4d823c9d06aaa91476b58e56e4d44c4112da2811 > -- > 2.34.1 >