1*7490f933Smatt /* $NetBSD: becc_button.c,v 1.4 2012/02/12 16:31:01 matt Exp $ */
298845103Sthorpej
398845103Sthorpej /*
498845103Sthorpej * Copyright (c) 2003 Wasabi Systems, Inc.
598845103Sthorpej * All rights reserved.
698845103Sthorpej *
798845103Sthorpej * Written by Jason R. Thorpe for Wasabi Systems, Inc.
898845103Sthorpej *
998845103Sthorpej * Redistribution and use in source and binary forms, with or without
1098845103Sthorpej * modification, are permitted provided that the following conditions
1198845103Sthorpej * are met:
1298845103Sthorpej * 1. Redistributions of source code must retain the above copyright
1398845103Sthorpej * notice, this list of conditions and the following disclaimer.
1498845103Sthorpej * 2. Redistributions in binary form must reproduce the above copyright
1598845103Sthorpej * notice, this list of conditions and the following disclaimer in the
1698845103Sthorpej * documentation and/or other materials provided with the distribution.
1798845103Sthorpej * 3. All advertising materials mentioning features or use of this software
1898845103Sthorpej * must display the following acknowledgement:
1998845103Sthorpej * This product includes software developed for the NetBSD Project by
2098845103Sthorpej * Wasabi Systems, Inc.
2198845103Sthorpej * 4. The name of Wasabi Systems, Inc. may not be used to endorse
2298845103Sthorpej * or promote products derived from this software without specific prior
2398845103Sthorpej * written permission.
2498845103Sthorpej *
2598845103Sthorpej * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
2698845103Sthorpej * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2798845103Sthorpej * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2898845103Sthorpej * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
2998845103Sthorpej * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
3098845103Sthorpej * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
3198845103Sthorpej * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
3298845103Sthorpej * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
3398845103Sthorpej * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
3498845103Sthorpej * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
3598845103Sthorpej * POSSIBILITY OF SUCH DAMAGE.
3698845103Sthorpej */
3798845103Sthorpej
3898845103Sthorpej /*
3998845103Sthorpej * Driver for the reset button on the ADI Engineering, Inc. Big Endian
4098845103Sthorpej * Companion Chip.
4198845103Sthorpej *
4298845103Sthorpej * When pressed for two seconds, the reset button performs a hard reset
4398845103Sthorpej * of the system. Shorter presses result in an interrupt being generated,
4498845103Sthorpej * which the operating system can use to trigger a graceful reboot.
4598845103Sthorpej */
4698845103Sthorpej
4708716eaeSlukem #include <sys/cdefs.h>
48*7490f933Smatt __KERNEL_RCSID(0, "$NetBSD: becc_button.c,v 1.4 2012/02/12 16:31:01 matt Exp $");
4908716eaeSlukem
5098845103Sthorpej #include <sys/param.h>
5198845103Sthorpej #include <sys/systm.h>
5298845103Sthorpej #include <sys/device.h>
5398845103Sthorpej
5498845103Sthorpej #include <arm/xscale/beccreg.h>
5598845103Sthorpej #include <arm/xscale/beccvar.h>
5698845103Sthorpej
5798845103Sthorpej #include <dev/sysmon/sysmonvar.h>
5898845103Sthorpej #include <dev/sysmon/sysmon_taskq.h>
5998845103Sthorpej
6098845103Sthorpej static int beccbut_attached; /* there can be only one */
6198845103Sthorpej
6298845103Sthorpej struct beccbut_softc {
63*7490f933Smatt device_t sc_dev;
6498845103Sthorpej struct sysmon_pswitch sc_smpsw;
6598845103Sthorpej void *sc_ih;
6698845103Sthorpej };
6798845103Sthorpej
6898845103Sthorpej static void
beccbut_pressed_event(void * arg)6998845103Sthorpej beccbut_pressed_event(void *arg)
7098845103Sthorpej {
7198845103Sthorpej struct beccbut_softc *sc = arg;
7298845103Sthorpej
7398845103Sthorpej sysmon_pswitch_event(&sc->sc_smpsw, PSWITCH_EVENT_PRESSED);
7498845103Sthorpej }
7598845103Sthorpej
7698845103Sthorpej static int
beccbut_intr(void * arg)7798845103Sthorpej beccbut_intr(void *arg)
7898845103Sthorpej {
7998845103Sthorpej struct beccbut_softc *sc = arg;
8098845103Sthorpej int rv;
8198845103Sthorpej
8298845103Sthorpej rv = sysmon_task_queue_sched(0, beccbut_pressed_event, sc);
8398845103Sthorpej if (rv != 0)
8498845103Sthorpej printf("%s: WARNING: unable to queue button pressed "
85*7490f933Smatt "callback: %d\n", device_xname(sc->sc_dev), rv);
8698845103Sthorpej
8798845103Sthorpej return (1);
8898845103Sthorpej }
8998845103Sthorpej
9098845103Sthorpej static int
beccbut_match(device_t parent,cfdata_t match,void * aux)91*7490f933Smatt beccbut_match(device_t parent, cfdata_t match, void *aux)
9298845103Sthorpej {
9398845103Sthorpej
9498845103Sthorpej return (beccbut_attached == 0);
9598845103Sthorpej }
9698845103Sthorpej
9798845103Sthorpej static void
beccbut_attach(device_t parent,device_t self,void * aux)98*7490f933Smatt beccbut_attach(device_t parent, device_t self, void *aux)
9998845103Sthorpej {
100*7490f933Smatt struct beccbut_softc *sc = device_private(self);
10198845103Sthorpej
102*7490f933Smatt aprint_normal(": Reset button\n");
103*7490f933Smatt aprint_naive(": Reset button\n");
10498845103Sthorpej
10598845103Sthorpej beccbut_attached = 1;
106*7490f933Smatt sc->sc_dev = self;
10798845103Sthorpej
10898845103Sthorpej sysmon_task_queue_init();
10998845103Sthorpej
110*7490f933Smatt sc->sc_smpsw.smpsw_name = device_xname(sc->sc_dev);
11198845103Sthorpej sc->sc_smpsw.smpsw_type = PSWITCH_TYPE_RESET;
11298845103Sthorpej
11398845103Sthorpej if (sysmon_pswitch_register(&sc->sc_smpsw) != 0) {
114*7490f933Smatt aprint_error_dev(sc->sc_dev,
115*7490f933Smatt "unable to register with sysmon\n");
11698845103Sthorpej return;
11798845103Sthorpej }
11898845103Sthorpej
11998845103Sthorpej sc->sc_ih = becc_intr_establish(ICU_PUSHBUTTON, IPL_TTY,
12098845103Sthorpej beccbut_intr, sc);
12198845103Sthorpej if (sc->sc_ih == NULL)
122*7490f933Smatt aprint_error_dev(sc->sc_dev,
123*7490f933Smatt "unable to establish interrupt handler\n");
12498845103Sthorpej }
12598845103Sthorpej
126*7490f933Smatt CFATTACH_DECL_NEW(beccbut, sizeof(struct beccbut_softc),
12798845103Sthorpej beccbut_match, beccbut_attach, NULL, NULL);
128