1*471aeecfSnaddy /* $OpenBSD: power.c,v 1.9 2022/04/06 18:59:26 naddy Exp $ */
218e4ae67Smartin
318e4ae67Smartin /*
418e4ae67Smartin * Copyright (c) 2007 Martin Reindl.
518e4ae67Smartin *
618e4ae67Smartin * Permission to use, copy, modify, and distribute this software for any
718e4ae67Smartin * purpose with or without fee is hereby granted, provided that the above
818e4ae67Smartin * copyright notice and this permission notice appear in all copies.
918e4ae67Smartin *
1018e4ae67Smartin * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1118e4ae67Smartin * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1218e4ae67Smartin * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1318e4ae67Smartin * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1418e4ae67Smartin * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1518e4ae67Smartin * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1618e4ae67Smartin * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1718e4ae67Smartin */
1818e4ae67Smartin
1918e4ae67Smartin #include <sys/param.h>
2018e4ae67Smartin #include <sys/systm.h>
2118e4ae67Smartin #include <sys/kernel.h>
2218e4ae67Smartin #include <sys/device.h>
2318e4ae67Smartin #include <sys/conf.h>
2418e4ae67Smartin #include <sys/proc.h>
2518e4ae67Smartin #include <sys/signalvar.h>
2618e4ae67Smartin
2718e4ae67Smartin #include <machine/bus.h>
2818e4ae67Smartin #include <machine/autoconf.h>
2918e4ae67Smartin
3018e4ae67Smartin #include <sh/include/devreg.h>
3118e4ae67Smartin
3218e4ae67Smartin #include <landisk/landisk/landiskreg.h>
3318e4ae67Smartin #include <landisk/dev/obiovar.h>
3418e4ae67Smartin
3518e4ae67Smartin struct power_softc {
3618e4ae67Smartin struct device sc_dev;
3718e4ae67Smartin void *sc_ih;
3818e4ae67Smartin };
3918e4ae67Smartin
4018e4ae67Smartin int power_match(struct device *, void *, void *);
4118e4ae67Smartin void power_attach(struct device *, struct device *, void *);
4218e4ae67Smartin int power_intr(void *aux);
4318e4ae67Smartin
44*471aeecfSnaddy const struct cfattach power_ca = {
4518e4ae67Smartin sizeof(struct power_softc),
4618e4ae67Smartin power_match,
4718e4ae67Smartin power_attach
4818e4ae67Smartin };
4918e4ae67Smartin
5018e4ae67Smartin struct cfdriver power_cd = {
5118e4ae67Smartin NULL, "power", DV_DULL
5218e4ae67Smartin };
5318e4ae67Smartin
5418e4ae67Smartin struct power_softc *power_softc;
5518e4ae67Smartin
5618e4ae67Smartin int
power_match(struct device * parent,void * match,void * aux)5718e4ae67Smartin power_match(struct device *parent, void *match, void *aux)
5818e4ae67Smartin {
5918e4ae67Smartin struct obio_attach_args *oa = aux;
60867e5136Smiod static struct obio_irq power_match_irq;
6118e4ae67Smartin
6218e4ae67Smartin oa->oa_nio = 0;
6318e4ae67Smartin oa->oa_niomem = 0;
64867e5136Smiod if (oa->oa_nirq == 0)
65867e5136Smiod oa->oa_irq = &power_match_irq;
6618e4ae67Smartin oa->oa_nirq = 1;
6718e4ae67Smartin oa->oa_irq[0].or_irq = LANDISK_INTR_PWRSW;
6818e4ae67Smartin
6918e4ae67Smartin return (1);
7018e4ae67Smartin }
7118e4ae67Smartin
7218e4ae67Smartin void
power_attach(struct device * parent,struct device * self,void * aux)7318e4ae67Smartin power_attach(struct device *parent, struct device *self, void *aux)
7418e4ae67Smartin {
7518e4ae67Smartin struct power_softc *sc = (void *)self;
7618e4ae67Smartin
7718e4ae67Smartin power_softc = sc;
7818e4ae67Smartin
7918e4ae67Smartin sc->sc_ih = extintr_establish(LANDISK_INTR_PWRSW, IPL_TTY,
8018e4ae67Smartin power_intr, sc, sc->sc_dev.dv_xname);
8118e4ae67Smartin if (sc->sc_ih == NULL) {
82189cf00fSmiod printf(": couldn't map interrupt\n");
8318e4ae67Smartin return;
8418e4ae67Smartin }
8518e4ae67Smartin
8618e4ae67Smartin printf("\n");
8718e4ae67Smartin }
8818e4ae67Smartin
8918e4ae67Smartin int
power_intr(void * arg)9018e4ae67Smartin power_intr(void *arg)
9118e4ae67Smartin {
92b2e0f490Snaddy extern int allowpowerdown;
9318e4ae67Smartin int status;
9418e4ae67Smartin
9518e4ae67Smartin status = (int8_t)_reg_read_1(LANDISK_BTNSTAT);
9618e4ae67Smartin if (status == -1) {
9718e4ae67Smartin return (0);
9818e4ae67Smartin }
9918e4ae67Smartin
10018e4ae67Smartin status = ~status;
10170c623daSmartin if (status & BTN_POWER_BIT) {
10218e4ae67Smartin #ifdef DEBUG
10318e4ae67Smartin printf("%s switched\n", sc->sc_dev.dv_xname);
104e97088d6Smpi db_enter();
105189cf00fSmiod #endif
10618e4ae67Smartin _reg_write_1(LANDISK_PWRSW_INTCLR, 1);
107b2e0f490Snaddy if (allowpowerdown == 1) {
108b2e0f490Snaddy allowpowerdown = 0;
109de4108eaSguenther prsignal(initprocess, SIGUSR1);
11070c623daSmartin }
11118e4ae67Smartin return (1);
11218e4ae67Smartin }
11318e4ae67Smartin return (0);
11418e4ae67Smartin }
115