openpic_iobus.c revision 127135
1124469Sgrehan/* 2124469Sgrehan * Copyright 2003 by Peter Grehan. All rights reserved. 3124469Sgrehan * 4124469Sgrehan * Redistribution and use in source and binary forms, with or without 5124469Sgrehan * modification, are permitted provided that the following conditions 6124469Sgrehan * are met: 7124469Sgrehan * 1. Redistributions of source code must retain the above copyright 8124469Sgrehan * notice, this list of conditions and the following disclaimer. 9124469Sgrehan * 2. Redistributions in binary form must reproduce the above copyright 10124469Sgrehan * notice, this list of conditions and the following disclaimer in the 11124469Sgrehan * documentation and/or other materials provided with the distribution. 12124469Sgrehan * 3. The name of the author may not be used to endorse or promote products 13124469Sgrehan * derived from this software without specific prior written permission. 14124469Sgrehan * 15124469Sgrehan * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16124469Sgrehan * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17124469Sgrehan * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18124469Sgrehan * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19124469Sgrehan * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 20124469Sgrehan * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21124469Sgrehan * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 22124469Sgrehan * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 23124469Sgrehan * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24124469Sgrehan * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25124469Sgrehan * SUCH DAMAGE. 26124469Sgrehan * 27124469Sgrehan */ 28124469Sgrehan 29124469Sgrehan/* 30124469Sgrehan * The psim iobus attachment for the OpenPIC interrupt controller. 31124469Sgrehan */ 32124469Sgrehan 33124469Sgrehan#include <sys/cdefs.h> 34124469Sgrehan__FBSDID("$FreeBSD: head/sys/powerpc/psim/openpic_iobus.c 127135 2004-03-17 17:50:55Z njl $"); 35124469Sgrehan 36124469Sgrehan#include <sys/param.h> 37124469Sgrehan#include <sys/systm.h> 38124469Sgrehan#include <sys/bus.h> 39124469Sgrehan#include <sys/conf.h> 40124469Sgrehan#include <sys/kernel.h> 41124469Sgrehan 42124469Sgrehan#include <dev/ofw/openfirm.h> 43124469Sgrehan 44124469Sgrehan#include <machine/bus.h> 45124469Sgrehan#include <machine/intr.h> 46124469Sgrehan#include <machine/intr_machdep.h> 47124469Sgrehan#include <machine/md_var.h> 48124469Sgrehan#include <machine/nexusvar.h> 49124469Sgrehan#include <machine/pio.h> 50124469Sgrehan#include <machine/resource.h> 51124469Sgrehan 52124469Sgrehan#include <vm/vm.h> 53124469Sgrehan#include <vm/pmap.h> 54124469Sgrehan 55124469Sgrehan#include <sys/rman.h> 56124469Sgrehan 57124469Sgrehan#include <machine/openpicvar.h> 58124469Sgrehan#include <powerpc/psim/iobusvar.h> 59124469Sgrehan 60124469Sgrehan#include "pic_if.h" 61124469Sgrehan 62124469Sgrehanstruct openpic_iobus_softc { 63124469Sgrehan struct openpic_softc osc; 64124469Sgrehan struct resource *sc_memr; /* iobus mem resource */ 65124469Sgrehan device_t sc_ndev; /* nexus device */ 66124469Sgrehan}; 67124469Sgrehan 68124469Sgrehanstatic struct openpic_iobus_softc *ppicsoftc; 69124469Sgrehan 70124469Sgrehan/* 71124469Sgrehan * MacIO interface 72124469Sgrehan */ 73124469Sgrehanstatic void openpic_psim_identify(driver_t *, device_t); 74124469Sgrehanstatic int openpic_psim_probe(device_t); 75124469Sgrehanstatic int openpic_psim_attach(device_t); 76124469Sgrehanstatic int openpic_iobus_probe(device_t); 77124469Sgrehanstatic int openpic_iobus_attach(device_t); 78124469Sgrehan 79124469Sgrehan/* 80124469Sgrehan * Nexus attachment 81124469Sgrehan */ 82124469Sgrehanstatic device_method_t openpic_psim_methods[] = { 83124469Sgrehan /* Device interface */ 84124469Sgrehan DEVMETHOD(device_identify, openpic_psim_identify), 85124469Sgrehan DEVMETHOD(device_probe, openpic_psim_probe), 86124469Sgrehan DEVMETHOD(device_attach, openpic_psim_attach), 87124469Sgrehan 88124469Sgrehan /* PIC interface */ 89124469Sgrehan DEVMETHOD(pic_allocate_intr, openpic_allocate_intr), 90124469Sgrehan DEVMETHOD(pic_setup_intr, openpic_setup_intr), 91124469Sgrehan DEVMETHOD(pic_teardown_intr, openpic_teardown_intr), 92124469Sgrehan DEVMETHOD(pic_release_intr, openpic_release_intr), 93124469Sgrehan 94124469Sgrehan { 0, 0 } 95124469Sgrehan}; 96124469Sgrehan 97124469Sgrehanstatic driver_t openpic_psim_driver = { 98124469Sgrehan "openpic", 99124469Sgrehan openpic_psim_methods, 100124469Sgrehan sizeof(struct openpic_iobus_softc) 101124469Sgrehan}; 102124469Sgrehan 103124469Sgrehanstatic devclass_t openpic_psim_devclass; 104124469Sgrehan 105124469SgrehanDRIVER_MODULE(openpic_psim, nexus, openpic_psim_driver, openpic_psim_devclass, 106124469Sgrehan 0, 0); 107124469Sgrehan 108124469Sgrehanstatic void 109124469Sgrehanopenpic_psim_identify(driver_t *driver, device_t parent) 110124469Sgrehan{ 111124469Sgrehan device_t child; 112124469Sgrehan phandle_t pic; 113124469Sgrehan 114124469Sgrehan pic = OF_finddevice("/iobus/opic"); 115124469Sgrehan if (pic == -1) 116124469Sgrehan return; 117124469Sgrehan 118124469Sgrehan child = BUS_ADD_CHILD(parent, 0, "openpic", 0); 119124469Sgrehan if (child != NULL) 120124469Sgrehan nexus_set_device_type(child, "psim"); 121124469Sgrehan} 122124469Sgrehan 123124469Sgrehanstatic int 124124469Sgrehanopenpic_psim_probe(device_t dev) 125124469Sgrehan{ 126124469Sgrehan char *name; 127124469Sgrehan char *type; 128124469Sgrehan 129124469Sgrehan name = nexus_get_name(dev); 130124469Sgrehan type = nexus_get_device_type(dev); 131124469Sgrehan 132124469Sgrehan if (strcmp(name, "openpic") != 0 || 133124469Sgrehan strcmp(type, "psim") != 0) 134124469Sgrehan return (ENXIO); 135124469Sgrehan 136124469Sgrehan device_set_desc(dev, OPENPIC_DEVSTR); 137124469Sgrehan return (0); 138124469Sgrehan} 139124469Sgrehan 140124469Sgrehanstatic int 141124469Sgrehanopenpic_psim_attach(device_t dev) 142124469Sgrehan{ 143124469Sgrehan KASSERT(ppicsoftc == NULL, ("iobus openpic: already probed")); 144124469Sgrehan ppicsoftc = device_get_softc(dev); 145124469Sgrehan ppicsoftc->sc_ndev = dev; 146124469Sgrehan 147124469Sgrehan nexus_install_intcntlr(dev); 148124469Sgrehan openpic_early_attach(dev); 149124469Sgrehan return (0); 150124469Sgrehan} 151124469Sgrehan 152124469Sgrehan/* 153124469Sgrehan * PSIM IOBus attachment 154124469Sgrehan */ 155124469Sgrehanstatic device_method_t openpic_iobus_methods[] = { 156124469Sgrehan /* Device interface */ 157124469Sgrehan DEVMETHOD(device_probe, openpic_iobus_probe), 158124469Sgrehan DEVMETHOD(device_attach, openpic_iobus_attach), 159124469Sgrehan 160124469Sgrehan { 0, 0 }, 161124469Sgrehan}; 162124469Sgrehan 163124469Sgrehanstatic driver_t openpic_iobus_driver = { 164124469Sgrehan "openpiciobus", 165124469Sgrehan openpic_iobus_methods, 166124469Sgrehan 0 167124469Sgrehan}; 168124469Sgrehan 169124469Sgrehanstatic devclass_t openpic_iobus_devclass; 170124469Sgrehan 171124469SgrehanDRIVER_MODULE(openpiciobus, iobus, openpic_iobus_driver, 172124469Sgrehan openpic_iobus_devclass, 0, 0); 173124469Sgrehan 174124469Sgrehanstatic int 175124469Sgrehanopenpic_iobus_probe(device_t dev) 176124469Sgrehan{ 177124469Sgrehan char *name; 178124469Sgrehan 179124469Sgrehan name = iobus_get_name(dev); 180124469Sgrehan if (strcmp(name, "interrupt-controller") != 0) 181124469Sgrehan return (ENXIO); 182124469Sgrehan 183124469Sgrehan /* 184124469Sgrehan * The description was already printed out in the nexus 185124469Sgrehan * probe, so don't do it again here 186124469Sgrehan */ 187124469Sgrehan device_set_desc(dev, "OpenPIC IOBus interrupt cell"); 188124469Sgrehan if (!bootverbose) 189124469Sgrehan device_quiet(dev); 190124469Sgrehan return (0); 191124469Sgrehan} 192124469Sgrehan 193124469Sgrehanstatic int 194124469Sgrehanopenpic_iobus_attach(device_t dev) 195124469Sgrehan{ 196124469Sgrehan struct openpic_iobus_softc *sc; 197124469Sgrehan int rid; 198124469Sgrehan 199124469Sgrehan sc = ppicsoftc; 200124469Sgrehan KASSERT(sc != NULL, ("pic not nexus-probed\n")); 201124469Sgrehan 202124469Sgrehan rid = 0; 203127135Snjl sc->sc_memr = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, 204124469Sgrehan RF_ACTIVE); 205124469Sgrehan 206124469Sgrehan if (sc->sc_memr == NULL) { 207124469Sgrehan device_printf(dev, "Could not alloc mem resource!\n"); 208124469Sgrehan return (ENXIO); 209124469Sgrehan } 210124469Sgrehan 211124469Sgrehan sc->osc.sc_psim = 1; 212124469Sgrehan sc->osc.sc_bt = rman_get_bustag(sc->sc_memr); 213124469Sgrehan sc->osc.sc_bh = rman_get_bushandle(sc->sc_memr); 214124469Sgrehan sc->osc.sc_altdev = dev; 215124469Sgrehan 216124469Sgrehan return (openpic_attach(sc->sc_ndev)); 217124469Sgrehan} 218124469Sgrehan 219124469Sgrehan 220