Standards-conformance and code deduplication:

- Use bus reference phandles in place of FDT offsets as IRQ domain keys
- Unify the identical macio/fdt/mambo OpenPIC drivers into one
- Be more forgiving (following ePAPR) about what we need from the device
  tree to identify an OpenPIC
- Correctly map all IRQs into an interrupt domain
- Set IRQ_*_CONFORM for interrupts on an unknown PIC type instead of
  failing attachment for that device.
This commit is contained in:
Nathan Whitehorn 2013-10-22 14:07:57 +00:00
parent 3231e8bddb
commit 17593f8612
7 changed files with 57 additions and 305 deletions

View File

@ -124,7 +124,6 @@ powerpc/mambo/mambocall.S optional mambo
powerpc/mambo/mambo.c optional mambo
powerpc/mambo/mambo_console.c optional mambo
powerpc/mambo/mambo_disk.c optional mambo
powerpc/mambo/mambo_openpic.c optional mambo
powerpc/mpc85xx/atpic.c optional mpc85xx isa
powerpc/mpc85xx/ds1553_bus_fdt.c optional ds1553 fdt
powerpc/mpc85xx/ds1553_core.c optional ds1553
@ -143,6 +142,7 @@ powerpc/ofw/ofw_syscons.c optional sc aim
powerpc/ofw/ofwcall32.S optional aim powerpc
powerpc/ofw/ofwcall64.S optional aim powerpc64
powerpc/ofw/ofwmagic.S optional aim
powerpc/ofw/openpic_ofw.c optional aim | fdt
powerpc/ofw/rtas.c optional aim
powerpc/powermac/ata_kauai.c optional powermac ata | powermac atamacio
powerpc/powermac/ata_macio.c optional powermac ata | powermac atamacio
@ -158,7 +158,6 @@ powerpc/powermac/kiic.c optional powermac kiic
powerpc/powermac/macgpio.c optional powermac pci
powerpc/powermac/macio.c optional powermac pci
powerpc/powermac/nvbl.c optional powermac nvbl
powerpc/powermac/openpic_macio.c optional powermac pci
powerpc/powermac/platform_powermac.c optional powermac
powerpc/powermac/powermac_thermal.c optional powermac
powerpc/powermac/pswitch.c optional powermac pswitch
@ -196,7 +195,6 @@ powerpc/powerpc/mmu_if.m standard
powerpc/powerpc/mp_machdep.c optional smp
powerpc/powerpc/nexus.c standard
powerpc/powerpc/openpic.c standard
powerpc/powerpc/openpic_fdt.c optional fdt
powerpc/powerpc/pic_if.m standard
powerpc/powerpc/pmap_dispatch.c standard
powerpc/powerpc/platform.c standard

View File

@ -478,21 +478,31 @@ fdt_intr_decode(phandle_t intr_parent, pcell_t *intr, int *interrupt,
int *trig, int *pol)
{
fdt_pic_decode_t intr_decode;
phandle_t intr_offset;
int i, rv;
intr_offset = OF_xref_phandle(intr_parent);
for (i = 0; fdt_pic_table[i] != NULL; i++) {
/* XXX check if pic_handle has interrupt-controller prop? */
intr_decode = fdt_pic_table[i];
rv = intr_decode(intr_parent, intr, interrupt, trig, pol);
rv = intr_decode(intr_offset, intr, interrupt, trig, pol);
if (rv == 0)
if (rv == 0) {
/* This was recognized as our PIC and decoded. */
*interrupt = FDT_MAP_IRQ(intr_parent, *interrupt);
return (0);
}
}
return (ENXIO);
/* Not in table, so guess */
*interrupt = FDT_MAP_IRQ(intr_parent, fdt32_to_cpu(*intr));
*trig = INTR_TRIGGER_CONFORM;
*pol = INTR_POLARITY_CONFORM;
return (0);
}
int
@ -500,7 +510,7 @@ fdt_intr_to_rl(phandle_t node, struct resource_list *rl,
struct fdt_sense_level *intr_sl)
{
phandle_t intr_par;
ihandle_t iph;
phandle_t iph;
pcell_t *intr;
pcell_t intr_cells;
int interrupt, trig, pol;
@ -517,8 +527,7 @@ fdt_intr_to_rl(phandle_t node, struct resource_list *rl,
debugf("no intr-parent phandle\n");
intr_par = OF_parent(node);
} else {
iph = fdt32_to_cpu(iph);
intr_par = OF_instance_to_package(iph);
intr_par = OF_xref_phandle(iph);
}
if (OF_getprop(intr_par, "#interrupt-cells", &intr_cells,
@ -540,7 +549,7 @@ fdt_intr_to_rl(phandle_t node, struct resource_list *rl,
interrupt = -1;
trig = pol = 0;
if (fdt_intr_decode(intr_par, &intr[i * intr_cells],
if (fdt_intr_decode(iph, &intr[i * intr_cells],
&interrupt, &trig, &pol) != 0) {
rv = ENXIO;
goto out;
@ -557,7 +566,7 @@ fdt_intr_to_rl(phandle_t node, struct resource_list *rl,
intr_sl[i].trig = trig;
intr_sl[i].pol = pol;
irq = FDT_MAP_IRQ(intr_par, interrupt);
irq = FDT_MAP_IRQ(iph, interrupt);
resource_list_add(rl, SYS_RES_IRQ, i, irq, irq, 1);
}
@ -570,7 +579,6 @@ int
fdt_get_phyaddr(phandle_t node, device_t dev, int *phy_addr, void **phy_sc)
{
phandle_t phy_node;
ihandle_t phy_ihandle;
pcell_t phy_handle, phy_reg;
uint32_t i;
device_t parent, child;
@ -579,9 +587,7 @@ fdt_get_phyaddr(phandle_t node, device_t dev, int *phy_addr, void **phy_sc)
sizeof(phy_handle)) <= 0)
return (ENXIO);
phy_ihandle = (ihandle_t)phy_handle;
phy_ihandle = fdt32_to_cpu(phy_ihandle);
phy_node = OF_instance_to_package(phy_ihandle);
phy_node = OF_xref_phandle(phy_handle);
if (OF_getprop(phy_node, "reg", (void *)&phy_reg,
sizeof(phy_reg)) <= 0)

View File

@ -317,7 +317,7 @@ fdt_pci_route_intr(int bus, int slot, int func, int pin,
trig, pol);
#if defined(__powerpc__)
powerpc_config_intr(FDT_MAP_IRQ(intr_par, *interrupt), trig,
powerpc_config_intr(FDT_MAP_IRQ(iph, *interrupt), trig,
pol);
#endif
return (0);

View File

@ -123,7 +123,8 @@ fdt_pic_decode_openpic(phandle_t node, pcell_t *intr, int *interrupt,
int *trig, int *pol)
{
if (!fdt_is_compatible(node, "chrp,open-pic"))
if (!fdt_is_compatible(node, "chrp,open-pic") &&
!fdt_is_type(node, "open-pic"))
return (ENXIO);
/*

View File

@ -1,179 +0,0 @@
/*-
* Copyright 2008 by Nathan Whitehorn. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/module.h>
#include <sys/bus.h>
#include <sys/conf.h>
#include <sys/kernel.h>
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/openfirm.h>
#include <machine/bus.h>
#include <machine/intr_machdep.h>
#include <machine/md_var.h>
#include <machine/pio.h>
#include <machine/resource.h>
#include <vm/vm.h>
#include <vm/pmap.h>
#include <sys/rman.h>
#include <machine/openpicvar.h>
#include "pic_if.h"
/*
* Mambo interface
*/
static int openpic_mambo_probe(device_t);
static int openpic_mambo_attach(device_t);
static int openpicbus_mambo_probe(device_t dev);
static int openpicbus_mambo_attach(device_t dev);
static struct resource *openpicbus_alloc_resource(device_t bus, device_t dev,
int type, int *rid, u_long start, u_long end, u_long count, u_int flags);
static device_method_t openpicbus_mambo_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, openpicbus_mambo_probe),
DEVMETHOD(device_attach, openpicbus_mambo_attach),
/* Bus interface */
DEVMETHOD(bus_alloc_resource, openpicbus_alloc_resource),
{0,0}
};
struct openpicbus_softc {
vm_offset_t picaddr;
};
static driver_t openpicbus_mambo_driver = {
"openpicbus",
openpicbus_mambo_methods,
sizeof(struct openpicbus_softc),
};
static device_method_t openpic_mambo_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, openpic_mambo_probe),
DEVMETHOD(device_attach, openpic_mambo_attach),
/* PIC interface */
DEVMETHOD(pic_config, openpic_config),
DEVMETHOD(pic_dispatch, openpic_dispatch),
DEVMETHOD(pic_enable, openpic_enable),
DEVMETHOD(pic_eoi, openpic_eoi),
DEVMETHOD(pic_ipi, openpic_ipi),
DEVMETHOD(pic_mask, openpic_mask),
DEVMETHOD(pic_unmask, openpic_unmask),
{ 0, 0 },
};
static driver_t openpic_mambo_driver = {
"openpic",
openpic_mambo_methods,
sizeof(struct openpic_softc),
};
static devclass_t openpicbus_devclass;
DRIVER_MODULE(openpicbus, nexus, openpicbus_mambo_driver,
openpicbus_devclass, 0, 0);
DRIVER_MODULE(openpic, openpicbus, openpic_mambo_driver,
openpic_devclass, 0, 0);
static int
openpicbus_mambo_probe(device_t dev)
{
const char *type = ofw_bus_get_type(dev);
if (type == NULL || strcmp(type, "open-pic") != 0)
return (ENXIO);
device_set_desc(dev, "Mambo OpenPIC Container");
return (0);
}
static int
openpicbus_mambo_attach(device_t dev)
{
uint64_t picaddr;
phandle_t nexus;
struct openpicbus_softc *sc;
sc = device_get_softc(dev);
nexus = OF_parent(ofw_bus_get_node(dev));
OF_getprop(nexus,"platform-open-pic",
&picaddr,sizeof(picaddr));
sc->picaddr = picaddr;
device_add_child(dev,"openpic",-1);
return (bus_generic_attach(dev));
}
static struct resource *
openpicbus_alloc_resource(device_t bus, device_t dev, int type, int *rid,
u_long start, u_long end, u_long count, u_int flags)
{
struct openpicbus_softc *sc;
sc = device_get_softc(bus);
count = 0x40000;
start = sc->picaddr;
end = start + count;
return (bus_alloc_resource(bus, type, rid, start, end, count, flags));
}
static int
openpic_mambo_probe(device_t dev)
{
device_set_desc(dev, OPENPIC_DEVSTR);
return (0);
}
static int
openpic_mambo_attach(device_t dev)
{
return (openpic_common_attach(dev,
ofw_bus_get_node(device_get_parent(dev))));
}

View File

@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$");
#include <sys/kernel.h>
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
#include <dev/ofw/openfirm.h>
#include <machine/bus.h>
@ -55,15 +56,15 @@ __FBSDID("$FreeBSD$");
#include "pic_if.h"
/*
* MacIO interface
* OFW interface
*/
static int openpic_macio_probe(device_t);
static int openpic_macio_attach(device_t);
static int openpic_ofw_probe(device_t);
static int openpic_ofw_attach(device_t);
static device_method_t openpic_macio_methods[] = {
static device_method_t openpic_ofw_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, openpic_macio_probe),
DEVMETHOD(device_attach, openpic_macio_attach),
DEVMETHOD(device_probe, openpic_ofw_probe),
DEVMETHOD(device_attach, openpic_ofw_attach),
/* PIC interface */
DEVMETHOD(pic_bind, openpic_bind),
@ -75,26 +76,35 @@ static device_method_t openpic_macio_methods[] = {
DEVMETHOD(pic_mask, openpic_mask),
DEVMETHOD(pic_unmask, openpic_unmask),
{ 0, 0 },
DEVMETHOD_END
};
static driver_t openpic_macio_driver = {
static driver_t openpic_ofw_driver = {
"openpic",
openpic_macio_methods,
openpic_ofw_methods,
sizeof(struct openpic_softc),
};
DRIVER_MODULE(openpic, macio, openpic_macio_driver, openpic_devclass, 0, 0);
DRIVER_MODULE(openpic, nexus, openpic_ofw_driver, openpic_devclass, 0, 0);
DRIVER_MODULE(openpic, simplebus, openpic_ofw_driver, openpic_devclass, 0, 0);
DRIVER_MODULE(openpic, macio, openpic_ofw_driver, openpic_devclass, 0, 0);
static int
openpic_macio_probe(device_t dev)
openpic_ofw_probe(device_t dev)
{
const char *type = ofw_bus_get_type(dev);
if (strcmp(type, "open-pic") != 0)
if (type == NULL)
return (ENXIO);
/* On some U4 systems, there is a phantom MPIC in the mac-io cell */
if (!ofw_bus_is_compatible(dev, "chrp,open-pic") &&
strcmp(type, "open-pic") != 0)
return (ENXIO);
/*
* On some U4 systems, there is a phantom MPIC in the mac-io cell.
* The uninorth driver will pick up the real PIC, so ignore it here.
*/
if (OF_finddevice("/u4") != (phandle_t)-1)
return (ENXIO);
@ -103,8 +113,17 @@ openpic_macio_probe(device_t dev)
}
static int
openpic_macio_attach(device_t dev)
openpic_ofw_attach(device_t dev)
{
return (openpic_common_attach(dev, ofw_bus_get_node(dev)));
phandle_t xref, node;
node = ofw_bus_get_node(dev);
if (OF_getprop(node, "phandle", &xref, sizeof(xref)) == -1 &&
OF_getprop(node, "ibm,phandle", &xref, sizeof(xref)) == -1 &&
OF_getprop(node, "linux,phandle", &xref, sizeof(xref)) == -1)
xref = node;
return (openpic_common_attach(dev, xref));
}

View File

@ -1,93 +0,0 @@
/*-
* Copyright (c) 2009-2010 The FreeBSD Foundation
* All rights reserved.
*
* This software was developed by Semihalf under sponsorship from
* the FreeBSD Foundation.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/bus.h>
#include <machine/bus.h>
#include <machine/intr_machdep.h>
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
#include <machine/openpicvar.h>
#include "pic_if.h"
static int openpic_fdt_probe(device_t);
static int openpic_fdt_attach(device_t);
static device_method_t openpic_fdt_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, openpic_fdt_probe),
DEVMETHOD(device_attach, openpic_fdt_attach),
/* PIC interface */
DEVMETHOD(pic_bind, openpic_bind),
DEVMETHOD(pic_config, openpic_config),
DEVMETHOD(pic_dispatch, openpic_dispatch),
DEVMETHOD(pic_enable, openpic_enable),
DEVMETHOD(pic_eoi, openpic_eoi),
DEVMETHOD(pic_ipi, openpic_ipi),
DEVMETHOD(pic_mask, openpic_mask),
DEVMETHOD(pic_unmask, openpic_unmask),
{ 0, 0 },
};
static driver_t openpic_fdt_driver = {
"openpic",
openpic_fdt_methods,
sizeof(struct openpic_softc)
};
DRIVER_MODULE(openpic, simplebus, openpic_fdt_driver, openpic_devclass, 0, 0);
static int
openpic_fdt_probe(device_t dev)
{
if (!ofw_bus_is_compatible(dev, "chrp,open-pic"))
return (ENXIO);
device_set_desc(dev, OPENPIC_DEVSTR);
return (BUS_PROBE_DEFAULT);
}
static int
openpic_fdt_attach(device_t dev)
{
return (openpic_common_attach(dev, ofw_bus_get_node(dev)));
}