All of lore.kernel.org
 help / color / mirror / Atom feed
From: Baorui Liu <baorliu@amd.com>
To: "Rafael J . Wysocki" <rafael@kernel.org>
Cc: Len Brown <lenb@kernel.org>,
	Mario Limonciello <superm1@kernel.org>,
	<linux-acpi@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
	<acpica-devel@lists.linux.dev>, Baorui Liu <baorliu@amd.com>
Subject: [PATCH] ACPI: button: Report wakeup key only for power button wakeups
Date: Thu, 6 Aug 2026 20:27:32 +0800	[thread overview]
Message-ID: <20260806122732.533-1-baorliu@amd.com> (raw)

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


             reply	other threads:[~2026-08-06 12:28 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-06 12:27 Baorui Liu [this message]
2026-08-07 14:12 ` [PATCH] ACPI: button: Report wakeup key only for power button wakeups 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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260806122732.533-1-baorliu@amd.com \
    --to=baorliu@amd.com \
    --cc=acpica-devel@lists.linux.dev \
    --cc=lenb@kernel.org \
    --cc=linux-acpi@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=rafael@kernel.org \
    --cc=superm1@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.