summaryrefslogtreecommitdiffstats
path: root/sys/powerpc/aim/nexus.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/powerpc/aim/nexus.c')
-rw-r--r--sys/powerpc/aim/nexus.c95
1 files changed, 54 insertions, 41 deletions
diff --git a/sys/powerpc/aim/nexus.c b/sys/powerpc/aim/nexus.c
index c2b754a..e31ef61 100644
--- a/sys/powerpc/aim/nexus.c
+++ b/sys/powerpc/aim/nexus.c
@@ -97,7 +97,7 @@ struct nexus_devinfo {
};
struct nexus_softc {
- device_t sc_pic;
+ struct rman sc_rman;
};
/*
@@ -182,12 +182,24 @@ nexus_probe(device_t dev)
phandle_t root;
phandle_t child;
struct nexus_softc *sc;
+ u_long start, end;
if ((root = OF_peer(0)) == -1)
panic("nexus_probe: OF_peer failed.");
sc = device_get_softc(dev);
+ start = 0;
+ end = INTR_VECTORS - 1;
+
+ sc->sc_rman.rm_start = start;
+ sc->sc_rman.rm_end = end;
+ sc->sc_rman.rm_type = RMAN_ARRAY;
+ sc->sc_rman.rm_descr = "Interrupt request lines";
+ if (rman_init(&sc->sc_rman) ||
+ rman_manage_region(&sc->sc_rman, start, end))
+ panic("nexus_probe IRQ rman");
+
/*
* Allow devices to identify
*/
@@ -302,31 +314,40 @@ nexus_write_ivar(device_t dev, device_t child, int which, uintptr_t value)
static int
nexus_setup_intr(device_t dev, device_t child, struct resource *res, int flags,
- driver_filter_t *filter, driver_intr_t *intr, void *arg, void **cookiep)
+ driver_filter_t *filter, driver_intr_t *ihand, void *arg, void **cookiep)
{
- struct nexus_softc *sc;
+ driver_t *driver;
+ int error;
- sc = device_get_softc(dev);
+ /* somebody tried to setup an irq that failed to allocate! */
+ if (res == NULL)
+ panic("nexus_setup_intr: NULL irq resource!");
+
+ *cookiep = 0;
+ if ((rman_get_flags(res) & RF_SHAREABLE) == 0)
+ flags |= INTR_EXCL;
+
+ driver = device_get_driver(child);
+
+ /*
+ * We depend here on rman_activate_resource() being idempotent.
+ */
+ error = rman_activate_resource(res);
+ if (error)
+ return (error);
- if (device_get_state(sc->sc_pic) != DS_ATTACHED)
- panic("nexus_setup_intr: no pic attached\n");
+ error = powerpc_setup_intr(device_get_nameunit(child),
+ rman_get_start(res), filter, ihand, arg, flags, cookiep);
- return (PIC_SETUP_INTR(sc->sc_pic, child, res, flags, filter, intr,
- arg, cookiep));
+ return (error);
}
static int
nexus_teardown_intr(device_t dev, device_t child, struct resource *res,
- void *ih)
+ void *cookie)
{
- struct nexus_softc *sc;
- sc = device_get_softc(dev);
-
- if (device_get_state(sc->sc_pic) != DS_ATTACHED)
- panic("nexus_teardown_intr: no pic attached\n");
-
- return (PIC_TEARDOWN_INTR(sc->sc_pic, child, res, ih));
+ return (powerpc_teardown_intr(cookie));
}
/*
@@ -337,10 +358,8 @@ static struct resource *
nexus_alloc_resource(device_t bus, device_t child, int type, int *rid,
u_long start, u_long end, u_long count, u_int flags)
{
- struct nexus_softc *sc;
- struct resource *rv;
-
- sc = device_get_softc(bus);
+ struct nexus_softc *sc;
+ struct resource *rv;
if (type != SYS_RES_IRQ) {
device_printf(bus, "unknown resource request from %s\n",
@@ -348,10 +367,21 @@ nexus_alloc_resource(device_t bus, device_t child, int type, int *rid,
return (NULL);
}
- if (device_get_state(sc->sc_pic) != DS_ATTACHED)
- panic("nexus_alloc_resource: no pic attached\n");
+ if (count == 0 || start + count - 1 != end) {
+ device_printf(bus, "invalid IRQ allocation from %s\n",
+ device_get_nameunit(child));
+ return (NULL);
+ }
- rv = PIC_ALLOCATE_INTR(sc->sc_pic, child, rid, start, flags);
+ sc = device_get_softc(bus);
+
+ rv = rman_reserve_resource(&sc->sc_rman, start, end, count,
+ flags, child);
+ if (rv == NULL) {
+ device_printf(bus, "IRQ allocation failed for %s\n",
+ device_get_nameunit(child));
+ } else
+ rman_set_rid(rv, *rid);
return (rv);
}
@@ -378,9 +408,6 @@ static int
nexus_release_resource(device_t bus, device_t child, int type, int rid,
struct resource *res)
{
- struct nexus_softc *sc;
-
- sc = device_get_softc(bus);
if (type != SYS_RES_IRQ) {
device_printf(bus, "unknown resource request from %s\n",
@@ -388,10 +415,7 @@ nexus_release_resource(device_t bus, device_t child, int type, int rid,
return (EINVAL);
}
- if (device_get_state(sc->sc_pic) != DS_ATTACHED)
- panic("nexus_release_resource: no pic attached\n");
-
- return (PIC_RELEASE_INTR(sc->sc_pic, child, rid, res));
+ return (rman_release_resource(res));
}
static device_t
@@ -418,17 +442,6 @@ nexus_device_from_node(device_t parent, phandle_t node)
return (cdev);
}
-int
-nexus_install_intcntlr(device_t dev)
-{
- struct nexus_softc *sc;
-
- sc = device_get_softc(device_get_parent(dev));
- sc->sc_pic = dev;
-
- return (0);
-}
-
static const char *
nexus_ofw_get_name(device_t bus, device_t dev)
{
OpenPOWER on IntegriCloud