1139825Simp/*- 2110439Sbenno * Copyright (C) 2002 Benno Rice. 3110439Sbenno * All rights reserved. 4110439Sbenno * 5110439Sbenno * Redistribution and use in source and binary forms, with or without 6110439Sbenno * modification, are permitted provided that the following conditions 7110439Sbenno * are met: 8110439Sbenno * 1. Redistributions of source code must retain the above copyright 9110439Sbenno * notice, this list of conditions and the following disclaimer. 10110439Sbenno * 2. Redistributions in binary form must reproduce the above copyright 11110439Sbenno * notice, this list of conditions and the following disclaimer in the 12110439Sbenno * documentation and/or other materials provided with the distribution. 13110439Sbenno * 14110439Sbenno * THIS SOFTWARE IS PROVIDED BY Benno Rice ``AS IS'' AND ANY EXPRESS OR 15110439Sbenno * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16110439Sbenno * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17110439Sbenno * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 18110439Sbenno * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19110439Sbenno * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 20110439Sbenno * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 21110439Sbenno * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 22110439Sbenno * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 23110439Sbenno * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24110439Sbenno * 25110439Sbenno * $FreeBSD$ 26110439Sbenno */ 27110439Sbenno 28110441Sbenno#include "opt_ddb.h" 29110441Sbenno 30110439Sbenno#include <sys/param.h> 31110439Sbenno#include <sys/systm.h> 32132519Sgallatin#include <sys/kdb.h> 33110439Sbenno#include <sys/kernel.h> 34132519Sgallatin#include <sys/module.h> 35110439Sbenno#include <sys/malloc.h> 36110439Sbenno#include <sys/bus.h> 37110439Sbenno#include <machine/bus.h> 38110439Sbenno#include <sys/rman.h> 39110439Sbenno 40110439Sbenno#include <machine/resource.h> 41110439Sbenno 42110439Sbenno#include <dev/ofw/openfirm.h> 43110439Sbenno 44110439Sbenno#include <powerpc/powermac/maciovar.h> 45110439Sbenno 46110439Sbennostruct pswitch_softc { 47110439Sbenno int sc_irqrid; 48110439Sbenno struct resource *sc_irq; 49110439Sbenno void *sc_ih; 50110439Sbenno}; 51110439Sbenno 52110439Sbennostatic int pswitch_probe(device_t); 53110439Sbennostatic int pswitch_attach(device_t); 54110439Sbenno 55167170Spisostatic int pswitch_intr(void *); 56110439Sbenno 57110439Sbennostatic device_method_t pswitch_methods[] = { 58110439Sbenno /* Device interface */ 59110439Sbenno DEVMETHOD(device_probe, pswitch_probe), 60110439Sbenno DEVMETHOD(device_attach, pswitch_attach), 61110439Sbenno 62110439Sbenno { 0, 0 } 63110439Sbenno}; 64110439Sbenno 65110439Sbennostatic driver_t pswitch_driver = { 66110439Sbenno "pswitch", 67110439Sbenno pswitch_methods, 68110439Sbenno sizeof(struct pswitch_softc) 69110439Sbenno}; 70110439Sbenno 71110439Sbennostatic devclass_t pswitch_devclass; 72110439Sbenno 73110439SbennoDRIVER_MODULE(pswitch, macio, pswitch_driver, pswitch_devclass, 0, 0); 74110439Sbenno 75110439Sbennostatic int 76110439Sbennopswitch_probe(device_t dev) 77110439Sbenno{ 78110439Sbenno char *type = macio_get_devtype(dev); 79110439Sbenno 80110439Sbenno if (strcmp(type, "gpio") != 0) 81110439Sbenno return (ENXIO); 82110439Sbenno 83110439Sbenno device_set_desc(dev, "GPIO Programmer's Switch"); 84110439Sbenno return (0); 85110439Sbenno} 86110439Sbenno 87110439Sbennostatic int 88110439Sbennopswitch_attach(device_t dev) 89110439Sbenno{ 90110439Sbenno struct pswitch_softc *sc; 91110439Sbenno phandle_t node, child; 92110439Sbenno char type[32]; 93110439Sbenno u_int irq[2]; 94110439Sbenno 95110439Sbenno sc = device_get_softc(dev); 96110439Sbenno node = macio_get_node(dev); 97110439Sbenno 98110439Sbenno for (child = OF_child(node); child != 0; child = OF_peer(child)) { 99110439Sbenno if (OF_getprop(child, "device_type", type, 32) == -1) 100110439Sbenno continue; 101110439Sbenno 102110439Sbenno if (strcmp(type, "programmer-switch") == 0) 103110439Sbenno break; 104110439Sbenno } 105110439Sbenno 106110439Sbenno if (child == 0) { 107110439Sbenno device_printf(dev, "could not find correct node\n"); 108110439Sbenno return (ENXIO); 109110439Sbenno } 110110439Sbenno 111110439Sbenno if (OF_getprop(child, "interrupts", irq, sizeof(irq)) == -1) { 112110439Sbenno device_printf(dev, "could not get interrupt\n"); 113110439Sbenno return (ENXIO); 114110439Sbenno } 115110439Sbenno 116110439Sbenno sc->sc_irqrid = 0; 117110439Sbenno sc->sc_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->sc_irqrid, 118110439Sbenno irq[0], irq[0], 1, RF_ACTIVE); 119110439Sbenno if (sc->sc_irq == NULL) { 120110439Sbenno device_printf(dev, "could not allocate interrupt\n"); 121110439Sbenno return (ENXIO); 122110439Sbenno } 123110439Sbenno 124166978Spiso if (bus_setup_intr(dev, sc->sc_irq, INTR_TYPE_MISC, 125166978Spiso pswitch_intr, NULL, dev, &sc->sc_ih) != 0) { 126110439Sbenno device_printf(dev, "could not setup interrupt\n"); 127110439Sbenno bus_release_resource(dev, SYS_RES_IRQ, sc->sc_irqrid, 128110439Sbenno sc->sc_irq); 129110439Sbenno return (ENXIO); 130110439Sbenno } 131110439Sbenno 132110439Sbenno return (0); 133110439Sbenno} 134110439Sbenno 135167170Spisostatic int 136110439Sbennopswitch_intr(void *arg) 137110439Sbenno{ 138110439Sbenno device_t dev; 139110439Sbenno 140110439Sbenno dev = (device_t)arg; 141110439Sbenno 142174898Srwatson kdb_enter(KDB_WHY_POWERPC, device_get_nameunit(dev)); 143167170Spiso return (FILTER_HANDLED); 144110439Sbenno} 145