Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F160295712
D57712.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
3 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
@@ -3792,6 +3792,13 @@
EVENTHANDLER_INVOKE(power_resume, stype);
+ /*
+ * Record the resume time so that acpi_event_{power,sleep}_button_sleep()
+ * can ignore a button press that firmware/EC replays as the wake event
+ * as part of this resume (see acpi_button_resume_replay()).
+ */
+ sc->acpi_resume_sbt = getsbinuptime();
+
/* Allow another sleep request after a while. */
callout_schedule(&acpi_sleep_timer, hz * ACPI_MINIMUM_AWAKETIME);
@@ -4147,6 +4154,48 @@
/*
* ACPICA Event Handlers (FixedEvent, also called from button notify handler)
*/
+/*
+ * The window after resume during which a button "press" is assumed to be the
+ * firmware/EC replaying the wake event rather than a genuine press.
+ *
+ * Per the ACPI specification a power or sleep button that is also a system
+ * wake source must report the wake as a wakeup notification (Notify 0x02),
+ * not a button press (Notify 0x80). Some firmware violates this: the
+ * embedded controller queues the physical key press that woke the machine
+ * and flushes it through its normal _Qxx query path as soon as it is
+ * reinitialized on resume. The replayed press is therefore indistinguishable
+ * from a real one and is delivered synchronously with resume (observed within
+ * a few milliseconds). Honoring it would re-enter the sleep state, producing
+ * a resume->suspend loop.
+ *
+ * A deliberate press cannot occur this quickly -- it arrives well after the
+ * display has come back -- so a sub-second window cleanly separates the
+ * replayed wake event from a real press without ignoring genuine input for
+ * any user-perceptible time. A sub-second comparison (rather than a
+ * whole-second one) is used so a replay near a one-second boundary is not
+ * misclassified.
+ */
+#define ACPI_BUTTON_REPLAY_WINDOW (SBT_1S / 2)
+
+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);
+}
+
static void
acpi_invoke_sleep_eventhandler(void *context)
{
@@ -4173,6 +4222,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_invoke_sleep_eventhandler, &sc->acpi_power_button_stype)))
return_VALUE (ACPI_INTERRUPT_NOT_HANDLED);
@@ -4203,6 +4254,8 @@
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_invoke_sleep_eventhandler, &sc->acpi_sleep_button_stype)))
return_VALUE (ACPI_INTERRUPT_NOT_HANDLED);
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
Wed, Jun 24, 12:45 AM (15 h, 56 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
34265898
Default Alt Text
D57712.diff (3 KB)
Attached To
Mode
D57712: acpi: ignore wake button press replayed by firmware on resume
Attached
Detach File
Event Timeline
Log In to Comment