Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F160406141
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,36 @@
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 a sleep event (Notify 0x80 instead of the spec-required 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 +4195,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 +4225,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
Thu, Jun 25, 4:45 AM (45 m, 14 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
34304799
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