openpic_iobus.c revision 139825
1139825Simp/*- 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 139825 2005-01-07 02:29:27Z imp $"); 35124469Sgrehan 36124469Sgrehan#include <sys/param.h> 37124469Sgrehan#include <sys/systm.h> 38131102Sgrehan#include <sys/module.h> 39124469Sgrehan#include <sys/bus.h> 40124469Sgrehan#include <sys/conf.h> 41124469Sgrehan#include <sys/kernel.h> 42124469Sgrehan 43124469Sgrehan#include <dev/ofw/openfirm.h> 44124469Sgrehan 45124469Sgrehan#include <machine/bus.h> 46124469Sgrehan#include <machine/intr.h> 47124469Sgrehan#include <machine/intr_machdep.h> 48124469Sgrehan#include <machine/md_var.h> 49124469Sgrehan#include <machine/nexusvar.h> 50124469Sgrehan#include <machine/pio.h> 51124469Sgrehan#include <machine/resource.h> 52124469Sgrehan 53124469Sgrehan#include <vm/vm.h> 54124469Sgrehan#include <vm/pmap.h> 55124469Sgrehan 56124469Sgrehan#include <sys/rman.h> 57124469Sgrehan 58124469Sgrehan#include <machine/openpicvar.h> 59124469Sgrehan#include <powerpc/psim/iobusvar.h> 60124469Sgrehan 61124469Sgrehan#include "pic_if.h" 62124469Sgrehan 63124469Sgrehanstruct openpic_iobus_softc { 64124469Sgrehan struct openpic_softc osc; 65124469Sgrehan struct resource *sc_memr; /* iobus mem resource */ 66124469Sgrehan device_t sc_ndev; /* nexus device */ 67124469Sgrehan}; 68124469Sgrehan 69124469Sgrehanstatic struct openpic_iobus_softc *ppicsoftc; 70124469Sgrehan 71124469Sgrehan/* 72124469Sgrehan * MacIO interface 73124469Sgrehan */ 74124469Sgrehanstatic void openpic_psim_identify(driver_t *, device_t); 75124469Sgrehanstatic int openpic_psim_probe(device_t); 76124469Sgrehanstatic int openpic_psim_attach(device_t); 77124469Sgrehanstatic int openpic_iobus_probe(device_t); 78124469Sgrehanstatic int openpic_iobus_attach(device_t); 79124469Sgrehan 80124469Sgrehan/* 81124469Sgrehan * Nexus attachment 82124469Sgrehan */ 83124469Sgrehanstatic device_method_t openpic_psim_methods[] = { 84124469Sgrehan /* Device interface */ 85124469Sgrehan DEVMETHOD(device_identify, openpic_psim_identify), 86124469Sgrehan DEVMETHOD(device_probe, openpic_psim_probe), 87124469Sgrehan DEVMETHOD(device_attach, openpic_psim_attach), 88124469Sgrehan 89124469Sgrehan /* PIC interface */ 90124469Sgrehan DEVMETHOD(pic_allocate_intr, openpic_allocate_intr), 91124469Sgrehan DEVMETHOD(pic_setup_intr, openpic_setup_intr), 92124469Sgrehan DEVMETHOD(pic_teardown_intr, openpic_teardown_intr), 93124469Sgrehan DEVMETHOD(pic_release_intr, openpic_release_intr), 94124469Sgrehan 95124469Sgrehan { 0, 0 } 96124469Sgrehan}; 97124469Sgrehan 98124469Sgrehanstatic driver_t openpic_psim_driver = { 99124469Sgrehan "openpic", 100124469Sgrehan openpic_psim_methods, 101124469Sgrehan sizeof(struct openpic_iobus_softc) 102124469Sgrehan}; 103124469Sgrehan 104124469Sgrehanstatic devclass_t openpic_psim_devclass; 105124469Sgrehan 106124469SgrehanDRIVER_MODULE(openpic_psim, nexus, openpic_psim_driver, openpic_psim_devclass, 107124469Sgrehan 0, 0); 108124469Sgrehan 109124469Sgrehanstatic void 110124469Sgrehanopenpic_psim_identify(driver_t *driver, device_t parent) 111124469Sgrehan{ 112124469Sgrehan device_t child; 113124469Sgrehan phandle_t pic; 114124469Sgrehan 115124469Sgrehan pic = OF_finddevice("/iobus/opic"); 116124469Sgrehan if (pic == -1) 117124469Sgrehan return; 118124469Sgrehan 119124469Sgrehan child = BUS_ADD_CHILD(parent, 0, "openpic", 0); 120124469Sgrehan if (child != NULL) 121124469Sgrehan nexus_set_device_type(child, "psim"); 122124469Sgrehan} 123124469Sgrehan 124124469Sgrehanstatic int 125124469Sgrehanopenpic_psim_probe(device_t dev) 126124469Sgrehan{ 127124469Sgrehan char *name; 128124469Sgrehan char *type; 129124469Sgrehan 130124469Sgrehan name = nexus_get_name(dev); 131124469Sgrehan type = nexus_get_device_type(dev); 132124469Sgrehan 133124469Sgrehan if (strcmp(name, "openpic") != 0 || 134124469Sgrehan strcmp(type, "psim") != 0) 135124469Sgrehan return (ENXIO); 136124469Sgrehan 137124469Sgrehan device_set_desc(dev, OPENPIC_DEVSTR); 138124469Sgrehan return (0); 139124469Sgrehan} 140124469Sgrehan 141124469Sgrehanstatic int 142124469Sgrehanopenpic_psim_attach(device_t dev) 143124469Sgrehan{ 144124469Sgrehan KASSERT(ppicsoftc == NULL, ("iobus openpic: already probed")); 145124469Sgrehan ppicsoftc = device_get_softc(dev); 146124469Sgrehan ppicsoftc->sc_ndev = dev; 147124469Sgrehan 148124469Sgrehan nexus_install_intcntlr(dev); 149124469Sgrehan openpic_early_attach(dev); 150124469Sgrehan return (0); 151124469Sgrehan} 152124469Sgrehan 153124469Sgrehan/* 154124469Sgrehan * PSIM IOBus attachment 155124469Sgrehan */ 156124469Sgrehanstatic device_method_t openpic_iobus_methods[] = { 157124469Sgrehan /* Device interface */ 158124469Sgrehan DEVMETHOD(device_probe, openpic_iobus_probe), 159124469Sgrehan DEVMETHOD(device_attach, openpic_iobus_attach), 160124469Sgrehan 161124469Sgrehan { 0, 0 }, 162124469Sgrehan}; 163124469Sgrehan 164124469Sgrehanstatic driver_t openpic_iobus_driver = { 165124469Sgrehan "openpiciobus", 166124469Sgrehan openpic_iobus_methods, 167124469Sgrehan 0 168124469Sgrehan}; 169124469Sgrehan 170124469Sgrehanstatic devclass_t openpic_iobus_devclass; 171124469Sgrehan 172124469SgrehanDRIVER_MODULE(openpiciobus, iobus, openpic_iobus_driver, 173124469Sgrehan openpic_iobus_devclass, 0, 0); 174124469Sgrehan 175124469Sgrehanstatic int 176124469Sgrehanopenpic_iobus_probe(device_t dev) 177124469Sgrehan{ 178124469Sgrehan char *name; 179124469Sgrehan 180124469Sgrehan name = iobus_get_name(dev); 181124469Sgrehan if (strcmp(name, "interrupt-controller") != 0) 182124469Sgrehan return (ENXIO); 183124469Sgrehan 184124469Sgrehan /* 185124469Sgrehan * The description was already printed out in the nexus 186124469Sgrehan * probe, so don't do it again here 187124469Sgrehan */ 188124469Sgrehan device_set_desc(dev, "OpenPIC IOBus interrupt cell"); 189124469Sgrehan if (!bootverbose) 190124469Sgrehan device_quiet(dev); 191124469Sgrehan return (0); 192124469Sgrehan} 193124469Sgrehan 194124469Sgrehanstatic int 195124469Sgrehanopenpic_iobus_attach(device_t dev) 196124469Sgrehan{ 197124469Sgrehan struct openpic_iobus_softc *sc; 198124469Sgrehan int rid; 199124469Sgrehan 200124469Sgrehan sc = ppicsoftc; 201124469Sgrehan KASSERT(sc != NULL, ("pic not nexus-probed\n")); 202124469Sgrehan 203124469Sgrehan rid = 0; 204127135Snjl sc->sc_memr = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, 205124469Sgrehan RF_ACTIVE); 206124469Sgrehan 207124469Sgrehan if (sc->sc_memr == NULL) { 208124469Sgrehan device_printf(dev, "Could not alloc mem resource!\n"); 209124469Sgrehan return (ENXIO); 210124469Sgrehan } 211124469Sgrehan 212124469Sgrehan sc->osc.sc_psim = 1; 213124469Sgrehan sc->osc.sc_bt = rman_get_bustag(sc->sc_memr); 214124469Sgrehan sc->osc.sc_bh = rman_get_bushandle(sc->sc_memr); 215124469Sgrehan sc->osc.sc_altdev = dev; 216124469Sgrehan 217124469Sgrehan return (openpic_attach(sc->sc_ndev)); 218124469Sgrehan} 219124469Sgrehan 220124469Sgrehan 221