From f3831b10f5c5f9b8fe11bc146b4c5b74a92fc5ba Mon Sep 17 00:00:00 2001 From: kettenis Date: Tue, 25 Jun 2024 11:57:10 +0000 Subject: [PATCH] Implement sleep button and EC events as wakeup events. Print the wakeup reason. ok mglocker@, deraadt@ --- sys/dev/acpi/acpi.c | 16 ++++++++++++++-- sys/dev/acpi/acpi_x86.c | 15 ++++++++++++++- sys/dev/acpi/acpiec.c | 16 +++++++++++++++- sys/dev/acpi/acpivar.h | 3 ++- 4 files changed, 45 insertions(+), 5 deletions(-) diff --git a/sys/dev/acpi/acpi.c b/sys/dev/acpi/acpi.c index ae1e3755836..b7b0fd59bdb 100644 --- a/sys/dev/acpi/acpi.c +++ b/sys/dev/acpi/acpi.c @@ -1,4 +1,4 @@ -/* $OpenBSD: acpi.c,v 1.431 2024/06/11 17:35:26 kettenis Exp $ */ +/* $OpenBSD: acpi.c,v 1.432 2024/06/25 11:57:10 kettenis Exp $ */ /* * Copyright (c) 2005 Thorsten Lockert * Copyright (c) 2005 Jordan Hargrave @@ -2115,6 +2115,11 @@ acpi_interrupt(void *arg) if (!(en & sts & (1L << jdx))) continue; + if (cpu_suspended) { + cpu_suspended = 0; + sc->sc_wakegpe = idx + jdx; + } + /* Signal this GPE */ gpe = idx + jdx; sc->gpe_table[gpe].active = 1; @@ -2149,8 +2154,10 @@ acpi_interrupt(void *arg) ACPI_PM1_PWRBTN_STS); sts &= ~ACPI_PM1_PWRBTN_STS; - if (cpu_suspended) + if (cpu_suspended) { cpu_suspended = 0; + sc->sc_wakegpe = -1; + } acpi_addtask(sc, acpi_pbtn_task, sc, 0); } @@ -2162,6 +2169,11 @@ acpi_interrupt(void *arg) ACPI_PM1_SLPBTN_STS); sts &= ~ACPI_PM1_SLPBTN_STS; + if (cpu_suspended) { + cpu_suspended = 0; + sc->sc_wakegpe = -2; + } + acpi_addtask(sc, acpi_sbtn_task, sc, 0); } if (sts) { diff --git a/sys/dev/acpi/acpi_x86.c b/sys/dev/acpi/acpi_x86.c index 97def00c044..243afdd95b8 100644 --- a/sys/dev/acpi/acpi_x86.c +++ b/sys/dev/acpi/acpi_x86.c @@ -1,4 +1,4 @@ -/* $OpenBSD: acpi_x86.c,v 1.21 2024/05/29 12:21:33 kettenis Exp $ */ +/* $OpenBSD: acpi_x86.c,v 1.22 2024/06/25 11:57:10 kettenis Exp $ */ /* * Copyright (c) 2005 Thorsten Lockert * Copyright (c) 2005 Jordan Hargrave @@ -147,6 +147,19 @@ suspend_finish(void *v) { struct acpi_softc *sc = v; + printf("wakeup event: "); + switch (sc->sc_wakegpe) { + case -1: + printf("PWRBTN\n"); + break; + case -2: + printf("SLPTN\n"); + break; + default: + printf("GPE 0x%x\n", sc->sc_wakegpe); + break; + } + acpi_record_event(sc, APM_NORMAL_RESUME); acpi_indicator(sc, ACPI_SST_WORKING); diff --git a/sys/dev/acpi/acpiec.c b/sys/dev/acpi/acpiec.c index 5ef24d5179d..e6add9e7ef0 100644 --- a/sys/dev/acpi/acpiec.c +++ b/sys/dev/acpi/acpiec.c @@ -1,4 +1,4 @@ -/* $OpenBSD: acpiec.c,v 1.65 2022/08/10 16:58:16 patrick Exp $ */ +/* $OpenBSD: acpiec.c,v 1.66 2024/06/25 11:57:10 kettenis Exp $ */ /* * Copyright (c) 2006 Can Erkin Acar * @@ -274,6 +274,9 @@ acpiec_attach(struct device *parent, struct device *self, void *aux) { struct acpiec_softc *sc = (struct acpiec_softc *)self; struct acpi_attach_args *aa = aux; +#ifndef SMALL_KERNEL + struct acpi_wakeq *wq; +#endif struct aml_value res; int64_t st; @@ -318,6 +321,17 @@ acpiec_attach(struct device *parent, struct device *self, void *aux) #ifndef SMALL_KERNEL acpi_set_gpehandler(sc->sc_acpi, sc->sc_gpe, acpiec_gpehandler, sc, GPE_EDGE); + + /* + * On many machines the EC is not listed as a wakeup device + * but is necessary to wake up from S0i. + */ + wq = malloc(sizeof(struct acpi_wakeq), M_DEVBUF, M_WAITOK | M_ZERO); + wq->q_node = sc->sc_devnode; + wq->q_gpe = sc->sc_gpe; + wq->q_state = ACPI_STATE_S0; + wq->q_enabled = 1; + SIMPLEQ_INSERT_TAIL(&sc->sc_acpi->sc_wakedevs, wq, q_next); #endif if (aml_evalname(sc->sc_acpi, sc->sc_devnode, "_GLK", 0, NULL, &res)) diff --git a/sys/dev/acpi/acpivar.h b/sys/dev/acpi/acpivar.h index b29c9a6b30e..ac89edbdc3d 100644 --- a/sys/dev/acpi/acpivar.h +++ b/sys/dev/acpi/acpivar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: acpivar.h,v 1.127 2024/05/13 19:56:37 kettenis Exp $ */ +/* $OpenBSD: acpivar.h,v 1.128 2024/06/25 11:57:10 kettenis Exp $ */ /* * Copyright (c) 2005 Thorsten Lockert * @@ -253,6 +253,7 @@ struct acpi_softc { int slp_typb; } sc_sleeptype[6]; int sc_lastgpe; + int sc_wakegpe; struct gpe_block *gpe_table; -- 2.20.1