Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F163466834
D57712.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
2 KB
Referenced Files
None
Subscribers
None
D57712.diff
View Options
diff --git a/sys/dev/acpica/acpi.c b/sys/dev/acpica/acpi.c
--- a/sys/dev/acpica/acpi.c
+++ b/sys/dev/acpica/acpi.c
@@ -3747,6 +3747,13 @@
slp_state &= ~ACPI_SS_GPE_SET;
}
if ((slp_state & ACPI_SS_DEV_SUSPEND) != 0) {
+ /*
+ * Record the resume time so a spurious power/sleep button press can be
+ * ignored for a grace period afterward (see the comment before
+ * ACPI_BUTTON_REPLAY_WINDOW). This must be taken before
+ * DEVICE_RESUME(), which re-initializes the EC that replays the press.
+ */
+ sc->acpi_resume_sbt = getsbinuptime();
EVENTHANDLER_INVOKE(acpi_pre_dev_resume, stype);
DEVICE_RESUME(root_bus);
slp_state &= ~ACPI_SS_DEV_SUSPEND;
@@ -4137,6 +4144,37 @@
return_VOID;
}
+/*
+ * Grace window after wakeup during which a power/sleep button press for suspend
+ * is ignored. Some firmware wrongly reports the depress that caused the wakeup
+ * as an "S0 Power/Sleep Button Pressed" notify (value 0x80) instead of the
+ * spec-required "Device Wake" notify (0x02); honoring it re-enters sleep
+ * immediately after resume. On the Framework Laptop 12 the replayed event
+ * arrives within ~620 ms of the recorded resume time, so a one-second window
+ * was chosen. See https://bugs.freebsd.org/296243 for the traces, timing
+ * data, and analysis.
+ */
+#define ACPI_BUTTON_REPLAY_WINDOW SBT_1S
+
+static bool
+acpi_button_resume_replay(struct acpi_softc *sc, const char *which)
+{
+ sbintime_t elapsed;
+
+ if (sc->acpi_resume_sbt == 0)
+ return (false);
+ elapsed = getsbinuptime() - sc->acpi_resume_sbt;
+ if (elapsed < 0 || elapsed >= ACPI_BUTTON_REPLAY_WINDOW)
+ return (false);
+ if (bootverbose) {
+ device_printf(sc->acpi_dev,
+ "ignoring %s button press %jd us after resume "
+ "(firmware replayed the wake event)\n",
+ which, (intmax_t)(elapsed / SBT_1US));
+ }
+ return (true);
+}
+
/*
* ACPICA Event Handlers (FixedEvent, also called from button notify handler)
*/
@@ -4158,6 +4196,8 @@
ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
#if defined(__amd64__) || defined(__i386__)
+ if (acpi_button_resume_replay(sc, "power"))
+ return_VALUE (ACPI_INTERRUPT_HANDLED);
if (ACPI_FAILURE(AcpiOsExecute(OSL_NOTIFY_HANDLER,
(ACPI_OSD_EXEC_CALLBACK)acpi_invoke_sleep_eventhandler,
&sc->acpi_power_button_stype)))
@@ -4186,6 +4226,9 @@
{
ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
+ if (acpi_button_resume_replay(sc, "sleep"))
+ return_VALUE (ACPI_INTERRUPT_HANDLED);
+
if (ACPI_FAILURE(AcpiOsExecute(OSL_NOTIFY_HANDLER,
(ACPI_OSD_EXEC_CALLBACK)acpi_invoke_sleep_eventhandler,
&sc->acpi_sleep_button_stype)))
diff --git a/sys/dev/acpica/acpivar.h b/sys/dev/acpica/acpivar.h
--- a/sys/dev/acpica/acpivar.h
+++ b/sys/dev/acpica/acpivar.h
@@ -56,6 +56,7 @@
int acpi_enabled;
enum power_stype acpi_stype;
int acpi_sleep_disabled;
+ sbintime_t acpi_resume_sbt; /* Uptime at last resume. */
/* Supported sleep states and types. */
bool acpi_supported_stypes[POWER_STYPE_COUNT];
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Jul 24, 10:41 AM (9 h, 3 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
35443718
Default Alt Text
D57712.diff (2 KB)
Attached To
Mode
D57712: acpi: ignore wake button press replayed by firmware on resume
Attached
Detach File
Event Timeline
Log In to Comment