xref: /openbsd/sys/arch/landisk/dev/power.c (revision cecf84d4)
1 /*	$OpenBSD: power.c,v 1.6 2014/07/11 08:18:30 guenther Exp $	*/
2 
3 /*
4  * Copyright (c) 2007 Martin Reindl.
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #include <sys/types.h>
20 #include <sys/param.h>
21 #include <sys/systm.h>
22 #include <sys/kernel.h>
23 #include <sys/device.h>
24 #include <sys/conf.h>
25 #include <sys/proc.h>
26 #include <sys/signalvar.h>
27 
28 #include <machine/bus.h>
29 #include <machine/autoconf.h>
30 
31 #include <sh/include/devreg.h>
32 
33 #include <landisk/landisk/landiskreg.h>
34 #include <landisk/dev/obiovar.h>
35 
36 struct power_softc {
37 	struct device		sc_dev;
38 	void			*sc_ih;
39 };
40 
41 int	power_match(struct device *, void *, void *);
42 void	power_attach(struct device *, struct device *, void *);
43 int	power_intr(void *aux);
44 
45 struct cfattach power_ca = {
46 	sizeof(struct power_softc),
47 	power_match,
48 	power_attach
49 };
50 
51 struct cfdriver power_cd = {
52 	NULL, "power", DV_DULL
53 };
54 
55 struct power_softc *power_softc;
56 
57 int
58 power_match(struct device *parent, void *match, void *aux)
59 {
60 	struct obio_attach_args *oa = aux;
61 	static struct obio_irq power_match_irq;
62 
63 	oa->oa_nio = 0;
64 	oa->oa_niomem = 0;
65 	if (oa->oa_nirq == 0)
66 		oa->oa_irq = &power_match_irq;
67 	oa->oa_nirq = 1;
68 	oa->oa_irq[0].or_irq = LANDISK_INTR_PWRSW;
69 
70 	return (1);
71 }
72 
73 void
74 power_attach(struct device *parent, struct device *self, void *aux)
75 {
76 	struct power_softc *sc = (void *)self;
77 
78 	power_softc = sc;
79 
80 	sc->sc_ih = extintr_establish(LANDISK_INTR_PWRSW, IPL_TTY,
81 	    power_intr, sc, sc->sc_dev.dv_xname);
82 	if (sc->sc_ih == NULL) {
83 		printf(": couldn't map interrupt\n");
84 		return;
85 	}
86 
87 	printf("\n");
88 }
89 
90 int
91 power_intr(void *arg)
92 {
93 	extern int allowpowerdown;
94 	int status;
95 
96 	status = (int8_t)_reg_read_1(LANDISK_BTNSTAT);
97 	if (status == -1) {
98 		return (0);
99 	}
100 
101 	status = ~status;
102 	if (status & BTN_POWER_BIT) {
103 #ifdef DEBUG
104 		printf("%s switched\n", sc->sc_dev.dv_xname);
105 		Debugger();
106 #endif
107 		_reg_write_1(LANDISK_PWRSW_INTCLR, 1);
108 		if (allowpowerdown == 1) {
109 			allowpowerdown = 0;
110 			prsignal(initprocess, SIGUSR1);
111 		}
112 		return (1);
113 	}
114 	return (0);
115 }
116