* [PATCH] ACPI: button: Report wakeup key only for power button wakeups
@ 2026-08-06 12:27 Baorui Liu
2026-08-07 14:12 ` Rafael J. Wysocki (Intel)
` (2 more replies)
0 siblings, 3 replies; 8+ messages in thread
From: Baorui Liu @ 2026-08-06 12:27 UTC (permalink / raw)
To: Rafael J . Wysocki
Cc: Len Brown, Mario Limonciello, linux-acpi, linux-kernel,
acpica-devel, Baorui Liu
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.
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.
Fixes: 16f70feaabe9 ("ACPI: button: trigger wakeup key events")
Signed-off-by: Baorui Liu <baorliu@amd.com>
---
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
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: [PATCH] ACPI: button: Report wakeup key only for power button wakeups
2026-08-06 12:27 [PATCH] ACPI: button: Report wakeup key only for power button wakeups Baorui Liu
@ 2026-08-07 14:12 ` Rafael J. Wysocki (Intel)
2026-08-19 8:55 ` [PATCH v2 0/1] " Baorui.Liu
2026-08-20 7:07 ` [PATCH] " kernel test robot
2 siblings, 0 replies; 8+ messages in thread
From: Rafael J. Wysocki (Intel) @ 2026-08-07 14:12 UTC (permalink / raw)
To: Baorui Liu
Cc: Rafael J . Wysocki, Len Brown, Mario Limonciello, linux-acpi,
linux-kernel, acpica-devel
On Thu, Aug 6, 2026 at 2:28 PM Baorui Liu <baorliu@amd.com> 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 <baorliu@amd.com>
> ---
> 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
>
^ permalink raw reply [flat|nested] 8+ messages in thread* [PATCH v2 0/1] ACPI: button: Report wakeup key only for power button wakeups
2026-08-06 12:27 [PATCH] ACPI: button: Report wakeup key only for power button wakeups Baorui Liu
2026-08-07 14:12 ` Rafael J. Wysocki (Intel)
@ 2026-08-19 8:55 ` Baorui.Liu
2026-08-19 8:55 ` [PATCH v2 1/1] " Baorui.Liu
2026-08-20 7:07 ` [PATCH] " kernel test robot
2 siblings, 1 reply; 8+ messages in thread
From: Baorui.Liu @ 2026-08-19 8:55 UTC (permalink / raw)
To: rafael
Cc: lenb, robert.moore, linux-acpi, linux-kernel, acpica-devel, Baorui.Liu
This v2 addresses the review feedback on v1 by documenting the
practical impact and by avoiding KEY_WAKEUP reporting from generic ACPI
sleep resume paths.
Problem reproduced on an AMD Android 15 Xen guest.
Input device mapping:
event0: LNXPWRBN Power Button, KEY_POWER + KEY_WAKEUP
event1: LNXSLPBN Sleep Button, KEY_SLEEP
Runtime trigger mapping:
xl trigger android power -> event0 KEY_POWER
xl trigger android sleep -> event1 KEY_SLEEP
without-fix kernel:
6.6.118-android15-14-maybe-dirty-gc3c82a22502d
echo mem > /sys/power/state
xl trigger android s3resume
/dev/input/event0 reports KEY_WAKEUP DOWN/UP.
with-fix v2 kernel:
6.6.118-android15-14-maybe-dirty-g5b231ece911d
The same non-power-button S3 resume path no longer reports KEY_WAKEUP
from /dev/input/event0. This was verified twice; both event0 logs are
empty.
The dmesg log confirms that the test path is S3 suspend/resume:
PM: suspend entry (deep)
ACPI: PM: Preparing to enter system sleep state S3
ACPI: PM: Waking up from system sleep state S3
Resume cause unknown
PM: suspend exit
A positive-control power-button S3 wake was attempted in the Xen guest:
echo mem > /sys/power/state
xl trigger android power
The guest remained suspended/offline and was recovered with:
xl trigger android s3resume
Therefore, xl trigger android power is not a reliable S3 wake source in
this Xen setup. That run is not used as positive-control power-button
wake evidence; it only confirms runtime input-device mapping.
Changes in v2:
- Add test evidence showing the practical impact.
- Track pending wakeup reporting in the ACPI button driver.
- Report KEY_WAKEUP only if a power-button event/notify is observed
while the ACPI button device is suspended.
- Stop synthesizing Power Button KEY_WAKEUP events from generic ACPI
sleep resume paths.
ACPI: button: Report wakeup key only for power button wakeups
drivers/acpi/button.c | 38 ++++++++++++++++-------------
drivers/acpi/sleep.c | 56 +++----------------------------------------
include/acpi/button.h | 5 ----
3 files changed, 24 insertions(+), 75 deletions(-)
--
2.34.1
^ permalink raw reply [flat|nested] 8+ messages in thread* [PATCH v2 1/1] ACPI: button: Report wakeup key only for power button wakeups
2026-08-19 8:55 ` [PATCH v2 0/1] " Baorui.Liu
@ 2026-08-19 8:55 ` Baorui.Liu
2026-09-09 14:41 ` Rafael J. Wysocki (Intel)
2026-09-17 14:31 ` [PATCH v3] " Baorui.Liu
0 siblings, 2 replies; 8+ messages in thread
From: Baorui.Liu @ 2026-08-19 8:55 UTC (permalink / raw)
To: rafael
Cc: lenb, robert.moore, linux-acpi, linux-kernel, acpica-devel, Baorui.Liu
The ACPI button driver reports KEY_WAKEUP from the Power Button input
device to let userspace know that the system was resumed by a power
button wakeup.
However, reporting KEY_WAKEUP from generic system resume paths can make
userspace observe a Power Button wakeup even when the system was resumed
by a different wake source.
This is reproducible on an AMD Android 15 Xen guest. With a kernel
without this fix, a non-power-button S3 resume:
echo mem > /sys/power/state
xl trigger android s3resume
makes the Power Button input device report KEY_WAKEUP. The same test on
a kernel with this fix no longer reports KEY_WAKEUP from the Power Button
input device.
Track whether a power button event/notify is observed while the ACPI
button device is suspended, and report KEY_WAKEUP on resume only in that
case. Do not synthesize a Power Button input event from generic ACPI
sleep resume code.
Signed-off-by: Baorui.Liu <baorliu@amd.com>
---
drivers/acpi/button.c | 38 ++++++++++++++++-------------
drivers/acpi/sleep.c | 56 +++----------------------------------------
include/acpi/button.h | 5 ----
3 files changed, 24 insertions(+), 75 deletions(-)
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
index 8d2843bece29..f9b6b7fff5bd 100644
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -175,6 +175,7 @@ struct acpi_button {
int last_state;
ktime_t last_time;
bool suspended;
+ bool wakeup_pending;
bool lid_state_initialized;
};
@@ -452,6 +453,9 @@ static void acpi_button_notify(acpi_handle handle, u32 event, void *data)
acpi_pm_wakeup_event(&device->dev);
button = acpi_driver_data(device);
+ if (button->type == ACPI_BUTTON_TYPE_POWER && button->suspended)
+ button->wakeup_pending = true;
+
if (button->suspended)
return;
@@ -468,23 +472,6 @@ 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);
- }
-
- return;
-}
-EXPORT_SYMBOL(acpi_power_button_wakeup);
-
static void acpi_button_notify_run(void *data)
{
acpi_button_notify(NULL, ACPI_BUTTON_NOTIFY_STATUS, data);
@@ -492,6 +479,12 @@ static void acpi_button_notify_run(void *data)
static u32 acpi_button_event(void *data)
{
+ struct acpi_device *device = data;
+ struct acpi_button *button = acpi_driver_data(device);
+
+ if (button->type == ACPI_BUTTON_TYPE_POWER && button->suspended)
+ button->wakeup_pending = true;
+
acpi_os_execute(OSL_NOTIFY_HANDLER, acpi_button_notify_run, data);
return ACPI_INTERRUPT_HANDLED;
}
@@ -503,11 +496,13 @@ static int acpi_button_suspend(struct device *dev)
struct acpi_button *button = acpi_driver_data(device);
button->suspended = true;
+ button->wakeup_pending = false;
return 0;
}
static int acpi_button_resume(struct device *dev)
{
+ struct input_dev *input;
struct acpi_device *device = to_acpi_device(dev);
struct acpi_button *button = acpi_driver_data(device);
@@ -518,6 +513,15 @@ static int acpi_button_resume(struct device *dev)
acpi_lid_initialize_state(device);
}
+ if (button->type == ACPI_BUTTON_TYPE_POWER && button->wakeup_pending) {
+ input = button->input;
+ input_report_key(input, KEY_WAKEUP, 1);
+ input_sync(input);
+ input_report_key(input, KEY_WAKEUP, 0);
+ input_sync(input);
+ button->wakeup_pending = false;
+ }
+
return 0;
}
#endif
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c
index 0adfcd0fb55e..d655248c20d4 100644
--- a/drivers/acpi/sleep.c
+++ b/drivers/acpi/sleep.c
@@ -22,7 +22,6 @@
#include <linux/syscore_ops.h>
#include <asm/io.h>
#include <trace/events/power.h>
-#include <acpi/button.h>
#include "internal.h"
#include "sleep.h"
@@ -105,8 +104,6 @@ u32 acpi_target_system_state(void)
}
EXPORT_SYMBOL_GPL(acpi_target_system_state);
-static bool pwr_btn_event_pending;
-
/*
* The ACPI specification wants us to save NVS memory regions during hibernation
* and to restore them during the subsequent resume. Windows does that also for
@@ -463,7 +460,6 @@ static int acpi_pm_prepare(void)
*/
static void acpi_pm_finish(void)
{
- struct acpi_device *pwr_btn_adev;
u32 acpi_state = acpi_target_sleep_state;
acpi_ec_unblock_transactions();
@@ -482,24 +478,6 @@ static void acpi_pm_finish(void)
acpi_target_sleep_state = ACPI_STATE_S0;
acpi_resume_power_resources();
-
- /* If we were woken with the fixed power button, provide a small
- * hint to userspace in the form of a wakeup event on the fixed power
- * button device (if it can be found).
- *
- * We delay the event generation til now, as the PM layer requires
- * timekeeping to be running before we generate events. */
- if (!pwr_btn_event_pending)
- return;
-
- pwr_btn_event_pending = false;
- 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);
- }
}
/**
@@ -604,27 +582,6 @@ static int acpi_suspend_enter(suspend_state_t pm_state)
/* Reprogram control registers */
acpi_leave_sleep_state_prep(acpi_state);
- /* ACPI 3.0 specs (P62) says that it's the responsibility
- * of the OSPM to clear the status bit [ implying that the
- * POWER_BUTTON event should not reach userspace ]
- *
- * However, we do generate a small hint for userspace in the form of
- * a wakeup event. We flag this condition for now and generate the
- * event later, as we're currently too early in resume to be able to
- * generate wakeup events.
- */
- if (ACPI_SUCCESS(status) && (acpi_state == ACPI_STATE_S3)) {
- 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) {
- acpi_clear_event(ACPI_EVENT_POWER_BUTTON);
- /* Flag for later */
- pwr_btn_event_pending = true;
- }
- }
-
/*
* Disable all GPE and clear their status bits before interrupts are
* enabled. Some GPEs (like wakeup GPEs) have no handlers and this can
@@ -797,19 +754,12 @@ bool acpi_s2idle_wake(void)
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);
- }
- }
+ if (pwr_btn_status & ACPI_EVENT_FLAG_STATUS_SET)
+ acpi_clear_event(ACPI_EVENT_POWER_BUTTON);
}
void acpi_s2idle_restore(void)
diff --git a/include/acpi/button.h b/include/acpi/button.h
index be02d3ff2896..af2fce5d2ee3 100644
--- a/include/acpi/button.h
+++ b/include/acpi/button.h
@@ -8,16 +8,11 @@
#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)
-{
- return;
-}
#endif /* IS_ENABLED(CONFIG_ACPI_BUTTON) */
#endif /* ACPI_BUTTON_H */
--
2.34.1
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: [PATCH v2 1/1] ACPI: button: Report wakeup key only for power button wakeups
2026-08-19 8:55 ` [PATCH v2 1/1] " Baorui.Liu
@ 2026-09-09 14:41 ` Rafael J. Wysocki (Intel)
2026-09-17 14:31 ` [PATCH v3] " Baorui.Liu
1 sibling, 0 replies; 8+ messages in thread
From: Rafael J. Wysocki (Intel) @ 2026-09-09 14:41 UTC (permalink / raw)
To: Baorui.Liu
Cc: rafael, lenb, robert.moore, linux-acpi, linux-kernel, acpica-devel
On Wed, Aug 19, 2026 at 10:56 AM Baorui.Liu <baorliu@amd.com> wrote:
>
> The ACPI button driver reports KEY_WAKEUP from the Power Button input
> device to let userspace know that the system was resumed by a power
> button wakeup.
>
> However, reporting KEY_WAKEUP from generic system resume paths can make
> userspace observe a Power Button wakeup even when the system was resumed
> by a different wake source.
>
> This is reproducible on an AMD Android 15 Xen guest. With a kernel
> without this fix, a non-power-button S3 resume:
>
> echo mem > /sys/power/state
> xl trigger android s3resume
>
> makes the Power Button input device report KEY_WAKEUP. The same test on
> a kernel with this fix no longer reports KEY_WAKEUP from the Power Button
> input device.
>
> Track whether a power button event/notify is observed while the ACPI
> button device is suspended, and report KEY_WAKEUP on resume only in that
> case. Do not synthesize a Power Button input event from generic ACPI
> sleep resume code.
>
> Signed-off-by: Baorui.Liu <baorliu@amd.com>
This doesn't apply on top of 7.3-rc2 for me, so please rebase and resend it.
When you resend it, don't add a cover letter (cover letters are only
needed for patch series, not for individual patches). If there is
information in the cover letter that is not covered by the patch
changelog, it can be copied there.
Thanks!
> ---
> drivers/acpi/button.c | 38 ++++++++++++++++-------------
> drivers/acpi/sleep.c | 56 +++----------------------------------------
> include/acpi/button.h | 5 ----
> 3 files changed, 24 insertions(+), 75 deletions(-)
>
> diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
> index 8d2843bece29..f9b6b7fff5bd 100644
> --- a/drivers/acpi/button.c
> +++ b/drivers/acpi/button.c
> @@ -175,6 +175,7 @@ struct acpi_button {
> int last_state;
> ktime_t last_time;
> bool suspended;
> + bool wakeup_pending;
> bool lid_state_initialized;
> };
>
> @@ -452,6 +453,9 @@ static void acpi_button_notify(acpi_handle handle, u32 event, void *data)
> acpi_pm_wakeup_event(&device->dev);
>
> button = acpi_driver_data(device);
> + if (button->type == ACPI_BUTTON_TYPE_POWER && button->suspended)
> + button->wakeup_pending = true;
> +
> if (button->suspended)
> return;
>
> @@ -468,23 +472,6 @@ 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);
> - }
> -
> - return;
> -}
> -EXPORT_SYMBOL(acpi_power_button_wakeup);
> -
> static void acpi_button_notify_run(void *data)
> {
> acpi_button_notify(NULL, ACPI_BUTTON_NOTIFY_STATUS, data);
> @@ -492,6 +479,12 @@ static void acpi_button_notify_run(void *data)
>
> static u32 acpi_button_event(void *data)
> {
> + struct acpi_device *device = data;
> + struct acpi_button *button = acpi_driver_data(device);
> +
> + if (button->type == ACPI_BUTTON_TYPE_POWER && button->suspended)
> + button->wakeup_pending = true;
> +
> acpi_os_execute(OSL_NOTIFY_HANDLER, acpi_button_notify_run, data);
> return ACPI_INTERRUPT_HANDLED;
> }
> @@ -503,11 +496,13 @@ static int acpi_button_suspend(struct device *dev)
> struct acpi_button *button = acpi_driver_data(device);
>
> button->suspended = true;
> + button->wakeup_pending = false;
> return 0;
> }
>
> static int acpi_button_resume(struct device *dev)
> {
> + struct input_dev *input;
> struct acpi_device *device = to_acpi_device(dev);
> struct acpi_button *button = acpi_driver_data(device);
>
> @@ -518,6 +513,15 @@ static int acpi_button_resume(struct device *dev)
> acpi_lid_initialize_state(device);
> }
>
> + if (button->type == ACPI_BUTTON_TYPE_POWER && button->wakeup_pending) {
> + input = button->input;
> + input_report_key(input, KEY_WAKEUP, 1);
> + input_sync(input);
> + input_report_key(input, KEY_WAKEUP, 0);
> + input_sync(input);
> + button->wakeup_pending = false;
> + }
> +
> return 0;
> }
> #endif
> diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c
> index 0adfcd0fb55e..d655248c20d4 100644
> --- a/drivers/acpi/sleep.c
> +++ b/drivers/acpi/sleep.c
> @@ -22,7 +22,6 @@
> #include <linux/syscore_ops.h>
> #include <asm/io.h>
> #include <trace/events/power.h>
> -#include <acpi/button.h>
>
> #include "internal.h"
> #include "sleep.h"
> @@ -105,8 +104,6 @@ u32 acpi_target_system_state(void)
> }
> EXPORT_SYMBOL_GPL(acpi_target_system_state);
>
> -static bool pwr_btn_event_pending;
> -
> /*
> * The ACPI specification wants us to save NVS memory regions during hibernation
> * and to restore them during the subsequent resume. Windows does that also for
> @@ -463,7 +460,6 @@ static int acpi_pm_prepare(void)
> */
> static void acpi_pm_finish(void)
> {
> - struct acpi_device *pwr_btn_adev;
> u32 acpi_state = acpi_target_sleep_state;
>
> acpi_ec_unblock_transactions();
> @@ -482,24 +478,6 @@ static void acpi_pm_finish(void)
> acpi_target_sleep_state = ACPI_STATE_S0;
>
> acpi_resume_power_resources();
> -
> - /* If we were woken with the fixed power button, provide a small
> - * hint to userspace in the form of a wakeup event on the fixed power
> - * button device (if it can be found).
> - *
> - * We delay the event generation til now, as the PM layer requires
> - * timekeeping to be running before we generate events. */
> - if (!pwr_btn_event_pending)
> - return;
> -
> - pwr_btn_event_pending = false;
> - 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);
> - }
> }
>
> /**
> @@ -604,27 +582,6 @@ static int acpi_suspend_enter(suspend_state_t pm_state)
> /* Reprogram control registers */
> acpi_leave_sleep_state_prep(acpi_state);
>
> - /* ACPI 3.0 specs (P62) says that it's the responsibility
> - * of the OSPM to clear the status bit [ implying that the
> - * POWER_BUTTON event should not reach userspace ]
> - *
> - * However, we do generate a small hint for userspace in the form of
> - * a wakeup event. We flag this condition for now and generate the
> - * event later, as we're currently too early in resume to be able to
> - * generate wakeup events.
> - */
> - if (ACPI_SUCCESS(status) && (acpi_state == ACPI_STATE_S3)) {
> - 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) {
> - acpi_clear_event(ACPI_EVENT_POWER_BUTTON);
> - /* Flag for later */
> - pwr_btn_event_pending = true;
> - }
> - }
> -
> /*
> * Disable all GPE and clear their status bits before interrupts are
> * enabled. Some GPEs (like wakeup GPEs) have no handlers and this can
> @@ -797,19 +754,12 @@ bool acpi_s2idle_wake(void)
>
> 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);
> - }
> - }
> + if (pwr_btn_status & ACPI_EVENT_FLAG_STATUS_SET)
> + acpi_clear_event(ACPI_EVENT_POWER_BUTTON);
> }
>
> void acpi_s2idle_restore(void)
> diff --git a/include/acpi/button.h b/include/acpi/button.h
> index be02d3ff2896..af2fce5d2ee3 100644
> --- a/include/acpi/button.h
> +++ b/include/acpi/button.h
> @@ -8,16 +8,11 @@
>
> #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)
> -{
> - return;
> -}
> #endif /* IS_ENABLED(CONFIG_ACPI_BUTTON) */
>
> #endif /* ACPI_BUTTON_H */
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 8+ messages in thread* [PATCH v3] ACPI: button: Report wakeup key only for power button wakeups
2026-08-19 8:55 ` [PATCH v2 1/1] " Baorui.Liu
2026-09-09 14:41 ` Rafael J. Wysocki (Intel)
@ 2026-09-17 14:31 ` Baorui.Liu
2026-09-18 14:36 ` Rafael J. Wysocki (Intel)
1 sibling, 1 reply; 8+ messages in thread
From: Baorui.Liu @ 2026-09-17 14:31 UTC (permalink / raw)
To: rafael
Cc: lenb, robert.moore, linux-acpi, linux-kernel, acpica-devel, Baorui.Liu
The ACPI button driver reports KEY_WAKEUP from the Power Button input
device to let userspace know that the system was resumed by a power
button wakeup.
However, reporting KEY_WAKEUP from generic system resume paths can make
userspace observe a Power Button wakeup even when the system was resumed
by a different wake source.
This is reproducible on an AMD Android 15 Xen guest. With a kernel
without this fix, a non-power-button S3 resume:
echo mem > /sys/power/state
xl trigger android s3resume
makes the Power Button input device report KEY_WAKEUP. The same test on
a kernel with this fix no longer reports KEY_WAKEUP from the Power Button
input device.
Track whether a power button event/notify is observed while the ACPI
button device is suspended, and report KEY_WAKEUP on resume only in that
case. Do not synthesize a Power Button input event from generic ACPI
sleep resume code.
Signed-off-by: Baorui.Liu <baorliu@amd.com>
---
drivers/acpi/button.c | 13 ++++++++++++-
drivers/acpi/sleep.c | 41 -----------------------------------------
2 files changed, 12 insertions(+), 42 deletions(-)
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
index cdbb1023a8ee..7a708fe351fb 100644
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -191,6 +191,7 @@ struct acpi_button {
bool last_state;
ktime_t last_time;
bool suspended;
+ bool wakeup_pending;
bool lid_state_initialized;
bool gpe_enabled;
};
@@ -476,6 +477,9 @@ static void acpi_button_notify(acpi_handle handle, u32 event, void *data)
acpi_pm_wakeup_event(button->dev);
+ if (button->type == ACPI_BUTTON_TYPE_POWER && button->suspended)
+ button->wakeup_pending = true;
+
if (button->suspended || event == ACPI_BUTTON_NOTIFY_WAKE)
return;
@@ -498,6 +502,11 @@ static void acpi_button_notify_run(void *data)
static u32 acpi_button_event(void *data)
{
+ struct acpi_button *button = data;
+
+ if (button->type == ACPI_BUTTON_TYPE_POWER && button->suspended)
+ button->wakeup_pending = true;
+
acpi_os_execute(OSL_NOTIFY_HANDLER, acpi_button_notify_run, data);
return ACPI_INTERRUPT_HANDLED;
}
@@ -508,6 +517,7 @@ static int acpi_button_suspend(struct device *dev)
struct acpi_button *button = dev_get_drvdata(dev);
button->suspended = true;
+ button->wakeup_pending = false;
return 0;
}
@@ -523,12 +533,13 @@ static int acpi_button_resume(struct device *dev)
acpi_lid_initialize_state(button);
}
- if (button->type == ACPI_BUTTON_TYPE_POWER) {
+ if (button->type == ACPI_BUTTON_TYPE_POWER && button->wakeup_pending) {
input = button->input;
input_report_key(input, KEY_WAKEUP, 1);
input_sync(input);
input_report_key(input, KEY_WAKEUP, 0);
input_sync(input);
+ button->wakeup_pending = false;
}
return 0;
}
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c
index 132a9df98471..7296e4bb0e4d 100644
--- a/drivers/acpi/sleep.c
+++ b/drivers/acpi/sleep.c
@@ -104,8 +104,6 @@ u32 acpi_target_system_state(void)
}
EXPORT_SYMBOL_GPL(acpi_target_system_state);
-static bool pwr_btn_event_pending;
-
/*
* The ACPI specification wants us to save NVS memory regions during hibernation
* and to restore them during the subsequent resume. Windows does that also for
@@ -484,7 +482,6 @@ static int acpi_pm_prepare(void)
*/
static void acpi_pm_finish(void)
{
- struct acpi_device *pwr_btn_adev;
u32 acpi_state = acpi_target_sleep_state;
acpi_ec_unblock_transactions();
@@ -503,23 +500,6 @@ static void acpi_pm_finish(void)
acpi_target_sleep_state = ACPI_STATE_S0;
acpi_resume_power_resources();
-
- /* If we were woken with the fixed power button, provide a small
- * hint to userspace in the form of a wakeup event on the fixed power
- * button device (if it can be found).
- *
- * We delay the event generation til now, as the PM layer requires
- * timekeeping to be running before we generate events. */
- if (!pwr_btn_event_pending)
- return;
-
- pwr_btn_event_pending = false;
- 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_dev_put(pwr_btn_adev);
- }
}
/**
@@ -626,27 +606,6 @@ static int acpi_suspend_enter(suspend_state_t pm_state)
/* Reprogram control registers */
acpi_leave_sleep_state_prep(acpi_state);
- /* ACPI 3.0 specs (P62) says that it's the responsibility
- * of the OSPM to clear the status bit [ implying that the
- * POWER_BUTTON event should not reach userspace ]
- *
- * However, we do generate a small hint for userspace in the form of
- * a wakeup event. We flag this condition for now and generate the
- * event later, as we're currently too early in resume to be able to
- * generate wakeup events.
- */
- if (ACPI_SUCCESS(status) && (acpi_state == ACPI_STATE_S3)) {
- 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) {
- acpi_clear_event(ACPI_EVENT_POWER_BUTTON);
- /* Flag for later */
- pwr_btn_event_pending = true;
- }
- }
-
/*
* Disable all GPE and clear their status bits before interrupts are
* enabled. Some GPEs (like wakeup GPEs) have no handlers and this can
--
2.34.1
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: [PATCH v3] ACPI: button: Report wakeup key only for power button wakeups
2026-09-17 14:31 ` [PATCH v3] " Baorui.Liu
@ 2026-09-18 14:36 ` Rafael J. Wysocki (Intel)
0 siblings, 0 replies; 8+ messages in thread
From: Rafael J. Wysocki (Intel) @ 2026-09-18 14:36 UTC (permalink / raw)
To: Baorui.Liu
Cc: rafael, lenb, robert.moore, linux-acpi, linux-kernel, acpica-devel
On Thu, Sep 17, 2026 at 4:31 PM Baorui.Liu <baorliu@amd.com> wrote:
>
> The ACPI button driver reports KEY_WAKEUP from the Power Button input
> device to let userspace know that the system was resumed by a power
> button wakeup.
>
> However, reporting KEY_WAKEUP from generic system resume paths can make
> userspace observe a Power Button wakeup even when the system was resumed
> by a different wake source.
>
> This is reproducible on an AMD Android 15 Xen guest. With a kernel
> without this fix, a non-power-button S3 resume:
>
> echo mem > /sys/power/state
> xl trigger android s3resume
>
> makes the Power Button input device report KEY_WAKEUP. The same test on
> a kernel with this fix no longer reports KEY_WAKEUP from the Power Button
> input device.
>
> Track whether a power button event/notify is observed while the ACPI
> button device is suspended, and report KEY_WAKEUP on resume only in that
> case. Do not synthesize a Power Button input event from generic ACPI
> sleep resume code.
>
> Signed-off-by: Baorui.Liu <baorliu@amd.com>
Please see
https://sashiko.dev/#/patchset/20260917143116.445-1-baorliu%40amd.com
and tell me what you think.
Thanks!
> ---
> drivers/acpi/button.c | 13 ++++++++++++-
> drivers/acpi/sleep.c | 41 -----------------------------------------
> 2 files changed, 12 insertions(+), 42 deletions(-)
>
> diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
> index cdbb1023a8ee..7a708fe351fb 100644
> --- a/drivers/acpi/button.c
> +++ b/drivers/acpi/button.c
> @@ -191,6 +191,7 @@ struct acpi_button {
> bool last_state;
> ktime_t last_time;
> bool suspended;
> + bool wakeup_pending;
> bool lid_state_initialized;
> bool gpe_enabled;
> };
> @@ -476,6 +477,9 @@ static void acpi_button_notify(acpi_handle handle, u32 event, void *data)
>
> acpi_pm_wakeup_event(button->dev);
>
> + if (button->type == ACPI_BUTTON_TYPE_POWER && button->suspended)
> + button->wakeup_pending = true;
> +
> if (button->suspended || event == ACPI_BUTTON_NOTIFY_WAKE)
> return;
>
> @@ -498,6 +502,11 @@ static void acpi_button_notify_run(void *data)
>
> static u32 acpi_button_event(void *data)
> {
> + struct acpi_button *button = data;
> +
> + if (button->type == ACPI_BUTTON_TYPE_POWER && button->suspended)
> + button->wakeup_pending = true;
> +
> acpi_os_execute(OSL_NOTIFY_HANDLER, acpi_button_notify_run, data);
> return ACPI_INTERRUPT_HANDLED;
> }
> @@ -508,6 +517,7 @@ static int acpi_button_suspend(struct device *dev)
> struct acpi_button *button = dev_get_drvdata(dev);
>
> button->suspended = true;
> + button->wakeup_pending = false;
> return 0;
> }
>
> @@ -523,12 +533,13 @@ static int acpi_button_resume(struct device *dev)
> acpi_lid_initialize_state(button);
> }
>
> - if (button->type == ACPI_BUTTON_TYPE_POWER) {
> + if (button->type == ACPI_BUTTON_TYPE_POWER && button->wakeup_pending) {
> input = button->input;
> input_report_key(input, KEY_WAKEUP, 1);
> input_sync(input);
> input_report_key(input, KEY_WAKEUP, 0);
> input_sync(input);
> + button->wakeup_pending = false;
> }
> return 0;
> }
> diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c
> index 132a9df98471..7296e4bb0e4d 100644
> --- a/drivers/acpi/sleep.c
> +++ b/drivers/acpi/sleep.c
> @@ -104,8 +104,6 @@ u32 acpi_target_system_state(void)
> }
> EXPORT_SYMBOL_GPL(acpi_target_system_state);
>
> -static bool pwr_btn_event_pending;
> -
> /*
> * The ACPI specification wants us to save NVS memory regions during hibernation
> * and to restore them during the subsequent resume. Windows does that also for
> @@ -484,7 +482,6 @@ static int acpi_pm_prepare(void)
> */
> static void acpi_pm_finish(void)
> {
> - struct acpi_device *pwr_btn_adev;
> u32 acpi_state = acpi_target_sleep_state;
>
> acpi_ec_unblock_transactions();
> @@ -503,23 +500,6 @@ static void acpi_pm_finish(void)
> acpi_target_sleep_state = ACPI_STATE_S0;
>
> acpi_resume_power_resources();
> -
> - /* If we were woken with the fixed power button, provide a small
> - * hint to userspace in the form of a wakeup event on the fixed power
> - * button device (if it can be found).
> - *
> - * We delay the event generation til now, as the PM layer requires
> - * timekeeping to be running before we generate events. */
> - if (!pwr_btn_event_pending)
> - return;
> -
> - pwr_btn_event_pending = false;
> - 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_dev_put(pwr_btn_adev);
> - }
> }
>
> /**
> @@ -626,27 +606,6 @@ static int acpi_suspend_enter(suspend_state_t pm_state)
> /* Reprogram control registers */
> acpi_leave_sleep_state_prep(acpi_state);
>
> - /* ACPI 3.0 specs (P62) says that it's the responsibility
> - * of the OSPM to clear the status bit [ implying that the
> - * POWER_BUTTON event should not reach userspace ]
> - *
> - * However, we do generate a small hint for userspace in the form of
> - * a wakeup event. We flag this condition for now and generate the
> - * event later, as we're currently too early in resume to be able to
> - * generate wakeup events.
> - */
> - if (ACPI_SUCCESS(status) && (acpi_state == ACPI_STATE_S3)) {
> - 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) {
> - acpi_clear_event(ACPI_EVENT_POWER_BUTTON);
> - /* Flag for later */
> - pwr_btn_event_pending = true;
> - }
> - }
> -
> /*
> * Disable all GPE and clear their status bits before interrupts are
> * enabled. Some GPEs (like wakeup GPEs) have no handlers and this can
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] ACPI: button: Report wakeup key only for power button wakeups
2026-08-06 12:27 [PATCH] ACPI: button: Report wakeup key only for power button wakeups Baorui Liu
2026-08-07 14:12 ` Rafael J. Wysocki (Intel)
2026-08-19 8:55 ` [PATCH v2 0/1] " Baorui.Liu
@ 2026-08-20 7:07 ` kernel test robot
2 siblings, 0 replies; 8+ messages in thread
From: kernel test robot @ 2026-08-20 7:07 UTC (permalink / raw)
To: Baorui Liu, Rafael J . Wysocki
Cc: oe-kbuild-all, Len Brown, Mario Limonciello, linux-acpi,
linux-kernel, acpica-devel, Baorui Liu
Hi Baorui,
kernel test robot noticed the following build warnings:
[auto build test WARNING on 4d823c9d06aaa91476b58e56e4d44c4112da2811]
url: https://github.com/intel-lab-lkp/linux/commits/Baorui-Liu/ACPI-button-Report-wakeup-key-only-for-power-button-wakeups/20260806-202732
base: 4d823c9d06aaa91476b58e56e4d44c4112da2811
patch link: https://lore.kernel.org/r/20260806122732.533-1-baorliu%40amd.com
patch subject: [PATCH] ACPI: button: Report wakeup key only for power button wakeups
config: csky-allmodconfig (https://download.01.org/0day-ci/archive/20260820/202608201432.sqYAY4nF-lkp@intel.com/config)
compiler: csky-linux-gcc (GCC) 16.1.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260820/202608201432.sqYAY4nF-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202608201432.sqYAY4nF-lkp@intel.com/
All warnings (new ones prefixed by >>):
In file included from drivers/gpu/drm/nouveau/nouveau_connector.c:27:
>> include/acpi/button.h:18:52: warning: 'struct acpi_device' declared inside parameter list will not be visible outside of this definition or declaration
18 | static inline void acpi_power_button_wakeup(struct acpi_device *device)
| ^~~~~~~~~~~
vim +18 include/acpi/button.h
17
> 18 static inline void acpi_power_button_wakeup(struct acpi_device *device)
19 {
20 }
21 #endif /* IS_ENABLED(CONFIG_ACPI_BUTTON) */
22
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2026-09-18 14:38 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-08-06 12:27 [PATCH] ACPI: button: Report wakeup key only for power button wakeups Baorui Liu
2026-08-07 14:12 ` Rafael J. Wysocki (Intel)
2026-08-19 8:55 ` [PATCH v2 0/1] " Baorui.Liu
2026-08-19 8:55 ` [PATCH v2 1/1] " Baorui.Liu
2026-09-09 14:41 ` Rafael J. Wysocki (Intel)
2026-09-17 14:31 ` [PATCH v3] " Baorui.Liu
2026-09-18 14:36 ` Rafael J. Wysocki (Intel)
2026-08-20 7:07 ` [PATCH] " kernel test robot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®