From 00c728103f85028bf0d146628ae2a7eaa95fd670 Mon Sep 17 00:00:00 2001 From: kettenis Date: Mon, 9 Jan 2023 20:29:35 +0000 Subject: [PATCH] Implement suspend on lid close. ok tobhe@, deraadt@ --- sys/arch/arm64/dev/aplsmc.c | 67 +++++++++++++++++++++++++------------ sys/arch/arm64/dev/apm.c | 27 ++++++++++++++- 2 files changed, 71 insertions(+), 23 deletions(-) diff --git a/sys/arch/arm64/dev/aplsmc.c b/sys/arch/arm64/dev/aplsmc.c index 01737c7c282..4117cb38e36 100644 --- a/sys/arch/arm64/dev/aplsmc.c +++ b/sys/arch/arm64/dev/aplsmc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: aplsmc.c,v 1.20 2022/11/26 17:23:15 tobhe Exp $ */ +/* $OpenBSD: aplsmc.c,v 1.21 2023/01/09 20:29:35 kettenis Exp $ */ /* * Copyright (c) 2021 Mark Kettenis * @@ -348,7 +348,32 @@ void aplsmc_handle_notification(struct aplsmc_softc *sc, uint64_t data) { extern int allowpowerdown; +#ifdef SUSPEND extern int cpu_suspended; + extern void suspend(void); + + if (cpu_suspended) { + switch (SMC_EV_TYPE(data)) { + case SMC_EV_TYPE_BTN: + switch (SMC_EV_SUBTYPE(data)) { + case SMC_PWRBTN_SHORT: + case SMC_PWRBTN_TOUCHID: + cpu_suspended = 0; + break; + } + break; + case SMC_EV_TYPE_LID: + switch (SMC_EV_SUBTYPE(data)) { + case SMC_LID_OPEN: + cpu_suspended = 0; + break; + } + break; + } + + return; + } +#endif switch (SMC_EV_TYPE(data)) { case SMC_EV_TYPE_BTN: @@ -356,11 +381,6 @@ aplsmc_handle_notification(struct aplsmc_softc *sc, uint64_t data) case SMC_PWRBTN_SHORT: case SMC_PWRBTN_TOUCHID: if (SMC_EV_DATA(data) == 1) { -#ifdef SUSPEND - if (cpu_suspended) { - cpu_suspended = 0; - } else -#endif if (allowpowerdown) { allowpowerdown = 0; prsignal(initprocess, SIGUSR2); @@ -379,23 +399,26 @@ aplsmc_handle_notification(struct aplsmc_softc *sc, uint64_t data) } break; case SMC_EV_TYPE_LID: - switch (SMC_EV_SUBTYPE(data)) { - case SMC_LID_OPEN: - if (simplefb_burn_hook) - simplefb_burn_hook(1); - break; - case SMC_LID_CLOSE: - if (simplefb_burn_hook) - simplefb_burn_hook(0); - break; - default: - printf("%s: SMV_EV_TYPE_LID 0x%016llx\n", - sc->sc_dev.dv_xname, data); - break; - } switch (lid_action) { - case 1: - /* XXX: suspend */ + case 0: + switch (SMC_EV_SUBTYPE(data)) { + case SMC_LID_OPEN: + if (simplefb_burn_hook) + simplefb_burn_hook(1); + break; + case SMC_LID_CLOSE: + if (simplefb_burn_hook) + simplefb_burn_hook(0); + break; + default: + printf("%s: SMV_EV_TYPE_LID 0x%016llx\n", + sc->sc_dev.dv_xname, data); + break; + } + case 1: +#ifdef SUSPEND + suspend(); +#endif break; case 2: /* XXX: hibernate */ diff --git a/sys/arch/arm64/dev/apm.c b/sys/arch/arm64/dev/apm.c index 94684daaebc..8953d48961c 100644 --- a/sys/arch/arm64/dev/apm.c +++ b/sys/arch/arm64/dev/apm.c @@ -1,4 +1,4 @@ -/* $OpenBSD: apm.c,v 1.19 2022/11/10 23:42:15 jsg Exp $ */ +/* $OpenBSD: apm.c,v 1.20 2023/01/09 20:29:35 kettenis Exp $ */ /*- * Copyright (c) 2001 Alexander Guy. All rights reserved. @@ -43,6 +43,7 @@ #include #include #include +#include #include #include @@ -55,6 +56,12 @@ #define DPRINTF(x) /**/ #endif +#ifdef SUSPEND +struct taskq *suspend_taskq; +struct task suspend_task; +void do_suspend(void *); +#endif + struct apm_softc { struct device sc_dev; struct klist sc_note; @@ -119,6 +126,11 @@ apmmatch(struct device *parent, void *match, void *aux) void apmattach(struct device *parent, struct device *self, void *aux) { +#ifdef SUSPEND + suspend_taskq = taskq_create("suspend", 1, IPL_NONE, 0); + task_set(&suspend_task, do_suspend, NULL); +#endif + acpiapm_open = apmopen; acpiapm_close = apmclose; acpiapm_ioctl = apmioctl; @@ -347,6 +359,19 @@ apm_record_event(u_int event, const char *src, const char *msg) #ifdef SUSPEND +void +do_suspend(void *v) +{ + sleep_state(v, SLEEP_SUSPEND); +} + +void +suspend(void) +{ + if (suspend_taskq) + task_add(suspend_taskq, &suspend_task); +} + #ifdef MULTIPROCESSOR void -- 2.20.1