Implement suspend on lid close.
authorkettenis <kettenis@openbsd.org>
Mon, 9 Jan 2023 20:29:35 +0000 (20:29 +0000)
committerkettenis <kettenis@openbsd.org>
Mon, 9 Jan 2023 20:29:35 +0000 (20:29 +0000)
ok tobhe@, deraadt@

sys/arch/arm64/dev/aplsmc.c
sys/arch/arm64/dev/apm.c

index 01737c7..4117cb3 100644 (file)
@@ -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 <kettenis@openbsd.org>
  *
@@ -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 */
index 94684da..8953d48 100644 (file)
@@ -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 <sys/event.h>
 #include <sys/reboot.h>
 #include <sys/hibernate.h>
+#include <sys/task.h>
 
 #include <machine/conf.h>
 #include <machine/cpu.h>
 #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