xref: /openbsd/sys/arch/macppc/dev/sysbutton.c (revision 89ed722c)
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