Connect macppc's power button and lid to the SUSPEND stubs
authorgkoehler <gkoehler@openbsd.org>
Sun, 23 Oct 2022 03:43:03 +0000 (03:43 +0000)
committergkoehler <gkoehler@openbsd.org>
Sun, 23 Oct 2022 03:43:03 +0000 (03:43 +0000)
A kernel with option SUSPEND now calls gosleep() if I run zzz(8),
press the power button (when machdep.pwraction=2), or close the lid
(when machdep.lidaction=1).  Because gosleep() is an empty stub, the
macppc does not really suspend; it only suspends some devices and
immediately resumes.

The interrupt from the power button or the lid needs some thread
(other than systq) to call sleep_state().  Use taskq_create(9) to
create another thread.

Add a call to device_register_wakeup().  Without this call,
sleep_state() does nothing.

ok kettenis@ deraadt@

sys/arch/macppc/dev/adb.c
sys/arch/macppc/dev/apm.c

index 540e093..8a351cd 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: adb.c,v 1.47 2022/10/21 22:42:36 gkoehler Exp $       */
+/*     $OpenBSD: adb.c,v 1.48 2022/10/23 03:43:03 gkoehler Exp $       */
 /*     $NetBSD: adb.c,v 1.6 1999/08/16 06:28:09 tsubai Exp $   */
 /*     $NetBSD: adb_direct.c,v 1.14 2000/06/08 22:10:45 tsubai Exp $   */
 
@@ -246,6 +246,11 @@ void       adb_cuda_fileserver_mode(void);
 #ifndef SMALL_KERNEL
 void   adb_shutdown(void *);
 struct task adb_shutdown_task = TASK_INITIALIZER(adb_shutdown, NULL);
+#ifdef SUSPEND
+void   adb_suspend(void *);
+struct task adb_suspend_task = TASK_INITIALIZER(adb_suspend, NULL);
+struct taskq *adb_suspendq;
+#endif
 #endif
 
 #ifdef ADB_DEBUG
@@ -848,6 +853,17 @@ adb_shutdown(void *arg)
                prsignal(initprocess, SIGUSR2);
        }
 }
+
+#ifdef SUSPEND
+void
+adb_suspend(void *arg)
+{
+       extern struct cfdriver apm_cd;
+
+       if (apm_cd.cd_ndevs > 0)
+               sleep_state(apm_cd.cd_devs[0], SLEEP_SUSPEND);
+}
+#endif
 #endif /* !SMALL_KERNEL */
 
 void
@@ -855,9 +871,11 @@ adb_lid_closed_intr(void)
 {
 #ifndef SMALL_KERNEL
        switch (lid_action) {
+#ifdef SUSPEND
        case 1:
-               /* Suspend. */
+               task_add(adb_suspendq, &adb_suspend_task);
                break;
+#endif
        case 2:
                /* Hibernate. */
                break;
@@ -873,9 +891,11 @@ adb_power_button_intr(void)
        case 1:
                task_add(systq, &adb_shutdown_task);
                break;
+#ifdef SUSPEND
        case 2:
-               /* Suspend. */
+               task_add(adb_suspendq, &adb_suspend_task);
                break;
+#endif
        }
 #endif
 }
@@ -1637,6 +1657,14 @@ adbattach(struct device *parent, struct device *self, void *aux)
        int totaladbs;
        int adbindex, adbaddr;
 
+#if !defined(SMALL_KERNEL) && defined(SUSPEND)
+       adb_suspendq = taskq_create(sc->sc_dev.dv_xname, 1, IPL_TTY, 0);
+       if (adb_suspendq == NULL) {
+               printf(": can't create taskq\n");
+               return;
+       }
+#endif
+
        ca->ca_reg[0] += ca->ca_baseaddr;
 
        sc->sc_regbase = mapiodev(ca->ca_reg[0], ca->ca_reg[1]);
index dbeecc3..9082d86 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: apm.c,v 1.33 2022/03/13 12:33:01 mpi Exp $    */
+/*     $OpenBSD: apm.c,v 1.34 2022/10/23 03:43:03 gkoehler Exp $       */
 
 /*-
  * Copyright (c) 2001 Alexander Guy.  All rights reserved.
@@ -131,6 +131,10 @@ apmattach(struct device *parent, struct device *self, void *aux)
 
        printf(": battery flags 0x%X, ", info.flags);
        printf("%d%% charged\n", ((info.cur_charge * 100) / info.max_charge));
+
+#ifdef SUSPEND
+       device_register_wakeup(self);
+#endif
 }
 
 int
@@ -352,7 +356,6 @@ sleep_showstate(void *v, int sleepmode)
 {
        switch (sleepmode) {
        case SLEEP_SUSPEND:
-               /* TODO blink the light */
                return 0;
        default:
                return EOPNOTSUPP;
@@ -362,7 +365,6 @@ sleep_showstate(void *v, int sleepmode)
 int
 sleep_setstate(void *v)
 {
-       printf("TODO sleep_setstate\n");
        return 0;
 }