From 17b371d9047d2f82419a508017ab859f6a0eb3e8 Mon Sep 17 00:00:00 2001 From: kettenis Date: Sat, 3 Sep 2022 18:05:10 +0000 Subject: [PATCH] Make sure we don't suspend if we have no way to wake up the machine. The idea is that device drivers that can wake up the machine register themselves by calling device_register_wakeup(). To prevent regressions on amd64, we let acpi(4) register itself as a wakeup device if the AML for the machine defines wakeup devices. This may be refined in the future. This diff will prevent people from suspending their arm64 SBCs without having a way to wake them up. For now the only driver that registers itself is axppmic(4), which means that at this moment only SBCs with an allwinner A64 or H5 SoC will actually support suspend/resume. ok mlarkin@, deraadt@ --- sys/dev/acpi/acpi.c | 7 ++++++- sys/dev/fdt/axppmic.c | 8 +++++++- sys/kern/subr_suspend.c | 14 +++++++++++++- sys/sys/device.h | 3 ++- 4 files changed, 28 insertions(+), 4 deletions(-) diff --git a/sys/dev/acpi/acpi.c b/sys/dev/acpi/acpi.c index 15373d47cb9..7571828aa01 100644 --- a/sys/dev/acpi/acpi.c +++ b/sys/dev/acpi/acpi.c @@ -1,4 +1,4 @@ -/* $OpenBSD: acpi.c,v 1.414 2022/08/10 16:58:16 patrick Exp $ */ +/* $OpenBSD: acpi.c,v 1.415 2022/09/03 18:05:10 kettenis Exp $ */ /* * Copyright (c) 2005 Thorsten Lockert * Copyright (c) 2005 Jordan Hargrave @@ -1158,6 +1158,11 @@ acpi_attach_common(struct acpi_softc *sc, paddr_t base) } printf("\n"); +#ifdef SUSPEND + if (wakeup_dev_ct > 0) + device_register_wakeup(&sc->sc_dev); +#endif + /* * ACPI is enabled now -- attach timer */ diff --git a/sys/dev/fdt/axppmic.c b/sys/dev/fdt/axppmic.c index 9363038376a..43afc6c62f2 100644 --- a/sys/dev/fdt/axppmic.c +++ b/sys/dev/fdt/axppmic.c @@ -1,4 +1,4 @@ -/* $OpenBSD: axppmic.c,v 1.15 2022/07/16 11:26:13 kettenis Exp $ */ +/* $OpenBSD: axppmic.c,v 1.16 2022/09/03 18:05:10 kettenis Exp $ */ /* * Copyright (c) 2017 Mark Kettenis * @@ -570,6 +570,12 @@ axppmic_attach_common(struct axppmic_softc *sc, const char *name, int node) powerdownfn = axp209_powerdown; } #endif + +#ifdef SUSPEND + /* AXP803 can wake us up. */ + if (strcmp(name, "x-powers,axp803") == 0) + device_register_wakeup(&sc->sc_dev); +#endif } void diff --git a/sys/kern/subr_suspend.c b/sys/kern/subr_suspend.c index 84512766916..59bc9dca07a 100644 --- a/sys/kern/subr_suspend.c +++ b/sys/kern/subr_suspend.c @@ -1,4 +1,4 @@ -/* $OpenBSD: subr_suspend.c,v 1.11 2022/08/14 01:58:28 jsg Exp $ */ +/* $OpenBSD: subr_suspend.c,v 1.12 2022/09/03 18:05:10 kettenis Exp $ */ /* * Copyright (c) 2005 Thorsten Lockert * Copyright (c) 2005 Jordan Hargrave @@ -32,6 +32,15 @@ #include "softraid.h" #include "wsdisplay.h" +/* Number of (active) wakeup devices in the system. */ +u_int wakeup_devices; + +void +device_register_wakeup(struct device *dev) +{ + wakeup_devices++; +} + int sleep_state(void *v, int sleepmode) { @@ -48,6 +57,9 @@ top: rndbuf = NULL; rndbuflen = 0; + if (sleepmode == SLEEP_SUSPEND && wakeup_devices == 0) + return EOPNOTSUPP; + if (sleep_showstate(v, sleepmode)) return EOPNOTSUPP; #if NWSDISPLAY > 0 diff --git a/sys/sys/device.h b/sys/sys/device.h index 1d1b5bcf80a..564cc14724c 100644 --- a/sys/sys/device.h +++ b/sys/sys/device.h @@ -1,4 +1,4 @@ -/* $OpenBSD: device.h,v 1.63 2022/04/07 09:37:32 tb Exp $ */ +/* $OpenBSD: device.h,v 1.64 2022/09/03 18:05:10 kettenis Exp $ */ /* $NetBSD: device.h,v 1.15 1996/04/09 20:55:24 cgd Exp $ */ /* @@ -228,6 +228,7 @@ void setroot(struct device *, int, int); struct device *getdisk(char *str, int len, int defpart, dev_t *devp); struct device *parsedisk(char *str, int len, int defpart, dev_t *devp); void device_register(struct device *, void *); +void device_register_wakeup(struct device *); int loadfirmware(const char *name, u_char **bufp, size_t *buflen); #define FIRMWARE_MAX 5*1024*1024 -- 2.20.1