Have the power button trigger a wakeup from suspend.
authorpatrick <patrick@openbsd.org>
Wed, 21 Dec 2022 23:26:54 +0000 (23:26 +0000)
committerpatrick <patrick@openbsd.org>
Wed, 21 Dec 2022 23:26:54 +0000 (23:26 +0000)
ok kettenis@

sys/dev/fdt/qcpdc.c
sys/dev/fdt/qcpon.c
sys/dev/fdt/qcspmi.c

index c0068c1..b33ca65 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: qcpdc.c,v 1.2 2022/12/16 18:08:08 patrick Exp $       */
+/*     $OpenBSD: qcpdc.c,v 1.3 2022/12/21 23:26:54 patrick Exp $       */
 /*
  * Copyright (c) 2022 Patrick Wildt <patrick@blueri.se>
  *
@@ -84,6 +84,7 @@ void  qcpdc_intr_disestablish(void *);
 void   qcpdc_intr_enable(void *);
 void   qcpdc_intr_disable(void *);
 void   qcpdc_intr_barrier(void *);
+void   qcpdc_intr_set_wakeup(void *);
 
 int
 qcpdc_match(struct device *parent, void *match, void *aux)
@@ -140,6 +141,7 @@ qcpdc_attach(struct device *parent, struct device *self, void *aux)
        sc->sc_ic.ic_enable = qcpdc_intr_enable;
        sc->sc_ic.ic_disable = qcpdc_intr_disable;
        sc->sc_ic.ic_barrier = qcpdc_intr_barrier;
+       sc->sc_ic.ic_set_wakeup = qcpdc_intr_set_wakeup;
        fdt_intr_register(&sc->sc_ic);
 
        printf("\n");
@@ -247,3 +249,11 @@ qcpdc_intr_barrier(void *cookie)
 
        intr_barrier(ih->ih_cookie);
 }
+
+void
+qcpdc_intr_set_wakeup(void *cookie)
+{
+       struct intrhand *ih = cookie;
+
+       intr_set_wakeup(ih->ih_cookie);
+}
index ee1f387..293b454 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: qcpon.c,v 1.2 2022/11/10 16:20:54 patrick Exp $       */
+/*     $OpenBSD: qcpon.c,v 1.3 2022/12/21 23:26:54 patrick Exp $       */
 /*
  * Copyright (c) 2022 Patrick Wildt <patrick@blueri.se>
  *
@@ -89,13 +89,17 @@ qcpon_attach(struct device *parent, struct device *self, void *aux)
 
        for (node = OF_child(saa->sa_node); node; node = OF_peer(node)) {
                if (OF_is_compatible(node, "qcom,pmk8350-pwrkey")) {
-                       sc->sc_pwrkey_ih = fdt_intr_establish(node, IPL_BIO,
-                           qcpon_pwrkey_intr, sc, sc->sc_dev.dv_xname);
+                       sc->sc_pwrkey_ih = fdt_intr_establish(node,
+                           IPL_BIO | IPL_WAKEUP, qcpon_pwrkey_intr, sc,
+                           sc->sc_dev.dv_xname);
                        if (sc->sc_pwrkey_ih == NULL) {
                                printf("%s: can't establish interrupt\n",
                                    sc->sc_dev.dv_xname);
                                continue;
                        }
+#ifdef SUSPEND
+                       device_register_wakeup(&sc->sc_dev);
+#endif
                }
        }
 }
@@ -104,13 +108,22 @@ int
 qcpon_pwrkey_intr(void *arg)
 {
        struct qcpon_softc *sc = arg;
+#ifdef SUSPEND
+       extern int cpu_suspended;
+#endif
 
        /* Ignore presses, handle releases. */
        sc->sc_pwrkey_debounce = (sc->sc_pwrkey_debounce + 1) % 2;
        if (sc->sc_pwrkey_debounce == 1)
                return 1;
 
-       task_add(systq, &sc->sc_powerdown_task);
+#ifdef SUSPEND
+       if (cpu_suspended)
+               cpu_suspended = 0;
+       else
+#endif
+               task_add(systq, &sc->sc_powerdown_task);
+
        return 1;
 }
 
index 697dcc6..f99e888 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: qcspmi.c,v 1.2 2022/11/10 12:16:06 patrick Exp $      */
+/*     $OpenBSD: qcspmi.c,v 1.3 2022/12/21 23:26:54 patrick Exp $      */
 /*
  * Copyright (c) 2022 Patrick Wildt <patrick@blueri.se>
  *
@@ -497,6 +497,9 @@ qcspmi_intr_establish(void *cookie, int *cells, int ipl,
            SPMI_IRQ_CLEAR, (1U << ih->ih_pin));
        qcspmi_intr_enable(ih);
 
+       if (ipl & IPL_WAKEUP)
+               intr_set_wakeup(sc->sc_ih);
+
        return ih;
 }