1 /* $OpenBSD: sysbutton.c,v 1.7 2022/03/13 12:33:01 mpi Exp $ */
2 /*
3 * Copyright (c) 2007 Gordon Willem Klok <gwk@openbsd.org>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18 #include <sys/param.h>
19 #include <sys/systm.h>
20 #include <sys/proc.h>
21 #include <sys/device.h>
22
23 #include <ddb/db_var.h>
24 #include <dev/ofw/openfirm.h>
25
26 #include <machine/bus.h>
27 #include <machine/autoconf.h>
28
29 struct sysbutton_softc {
30 struct device sc_dev;
31 int sc_node;
32 int sc_intr;
33 };
34
35 int sysbutton_match(struct device *, void *, void *);
36 void sysbutton_attach(struct device *, struct device *, void *);
37 int sysbutton_intr(void *);
38
39 const struct cfattach sysbutton_ca = {
40 sizeof(struct sysbutton_softc), sysbutton_match,
41 sysbutton_attach
42 };
43
44 struct cfdriver sysbutton_cd = {
45 NULL, "sysbutton", DV_DULL
46 };
47
48 int
sysbutton_match(struct device * parent,void * arg,void * aux)49 sysbutton_match(struct device *parent, void *arg, void *aux)
50 {
51 struct confargs *ca = aux;
52
53 if (strcmp(ca->ca_name, "indicatorSwitch-gpio") == 0)
54 return 1;
55
56 return 0;
57 }
58
59 void
sysbutton_attach(struct device * parent,struct device * self,void * aux)60 sysbutton_attach(struct device *parent, struct device *self, void *aux)
61 {
62 struct sysbutton_softc *sc = (struct sysbutton_softc *)self;
63 struct confargs *ca = aux;
64 int intr[2];
65
66 sc->sc_node = ca->ca_node;
67
68 OF_getprop(sc->sc_node, "interrupts", intr, sizeof(intr));
69 sc->sc_intr = intr[0];
70
71 printf(": irq %d\n", sc->sc_intr);
72
73 mac_intr_establish(parent, sc->sc_intr, IST_EDGE,
74 IPL_NONE, sysbutton_intr, sc, sc->sc_dev.dv_xname);
75 }
76
77 int
sysbutton_intr(void * v)78 sysbutton_intr(void *v)
79 {
80
81 /*
82 * XXX: Holding this button causes an interrupt storm if
83 * ddb.console=0.
84 */
85 #ifdef DDB
86 if (db_console)
87 db_enter();
88 #endif
89
90 return 1;
91 }
92