xref: /netbsd-src/sys/arch/arm/xscale/becc_button.c (revision 7490f9330505725b4cdef5ec3774397dc5644261)
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