summaryrefslogtreecommitdiffstats
path: root/sys/arm
diff options
context:
space:
mode:
authorsam <sam@FreeBSD.org>2009-03-10 16:42:49 +0000
committersam <sam@FreeBSD.org>2009-03-10 16:42:49 +0000
commit3c6380766d1e220490dcc531c718ccdc9ecadc8a (patch)
tree2d4b2dc189e3f6015b162502bcc94f61534c4ee4 /sys/arm
parentb7b3dfd99898d4ce3982d10f567e4eec6b6c0ddd (diff)
downloadFreeBSD-src-3c6380766d1e220490dcc531c718ccdc9ecadc8a.zip
FreeBSD-src-3c6380766d1e220490dcc531c718ccdc9ecadc8a.tar.gz
catch up with r189306; handle delayed activation of resources
Submitted by: jhb
Diffstat (limited to 'sys/arm')
-rw-r--r--sys/arm/xscale/ixp425/ixp425.c41
-rw-r--r--sys/arm/xscale/ixp425/ixp425_pci.c41
2 files changed, 57 insertions, 25 deletions
diff --git a/sys/arm/xscale/ixp425/ixp425.c b/sys/arm/xscale/ixp425/ixp425.c
index f2366de..d8cce84 100644
--- a/sys/arm/xscale/ixp425/ixp425.c
+++ b/sys/arm/xscale/ixp425/ixp425.c
@@ -362,8 +362,10 @@ ixp425_alloc_resource(device_t dev, device_t child, int type, int *rid,
struct rman *rmanp;
struct resource *rv;
uint32_t vbase, addr;
+ int needactivate = flags & RF_ACTIVE;
int irq;
+ flags &= ~RF_ACTIVE;
switch (type) {
case SYS_RES_IRQ:
rmanp = &sc->sc_irq_rman;
@@ -382,6 +384,7 @@ ixp425_alloc_resource(device_t dev, device_t child, int type, int *rid,
if (BUS_READ_IVAR(dev, child, IXP425_IVAR_ADDR, &addr) == 0) {
start = addr;
end = start + 0x1000; /* XXX */
+ count = end - start;
}
if (getvbase(start, end - start, &vbase) != 0) {
/* likely means above table needs to be updated */
@@ -391,20 +394,41 @@ ixp425_alloc_resource(device_t dev, device_t child, int type, int *rid,
}
rv = rman_reserve_resource(rmanp, start, end, count,
flags, child);
- if (rv != NULL) {
+ if (rv != NULL)
rman_set_rid(rv, *rid);
- if (strcmp(device_get_name(child), "uart") == 0)
- rman_set_bustag(rv, &ixp425_a4x_bs_tag);
- else
- rman_set_bustag(rv, sc->sc_iot);
- rman_set_bushandle(rv, vbase);
- }
break;
default:
rv = NULL;
break;
}
- return rv;
+ if (rv != NULL && needactivate) {
+ if (bus_activate_resource(child, type, *rid, rv)) {
+ rman_release_resource(rv);
+ return (NULL);
+ }
+ }
+ return (rv);
+}
+
+static int
+ixp425_activate_resource(device_t dev, device_t child, int type, int rid,
+ struct resource *r)
+{
+ struct ixp425_softc *sc = device_get_softc(dev);
+ int error;
+ uint32_t vbase;
+
+ if (type == SYS_RES_MEMORY) {
+ error = getvbase(rman_get_start(r), rman_get_size(r), &vbase);
+ if (error)
+ return (error);
+ if (strcmp(device_get_name(child), "uart") == 0)
+ rman_set_bustag(r, &ixp425_a4x_bs_tag);
+ else
+ rman_set_bustag(r, sc->sc_iot);
+ rman_set_bushandle(r, vbase);
+ }
+ return (rman_activate_resource(r));
}
static __inline void
@@ -472,6 +496,7 @@ static device_method_t ixp425_methods[] = {
DEVMETHOD(bus_read_ivar, ixp425_read_ivar),
DEVMETHOD(bus_alloc_resource, ixp425_alloc_resource),
+ DEVMETHOD(bus_activate_resource, ixp425_activate_resource),
DEVMETHOD(bus_setup_intr, ixp425_setup_intr),
DEVMETHOD(bus_teardown_intr, ixp425_teardown_intr),
diff --git a/sys/arm/xscale/ixp425/ixp425_pci.c b/sys/arm/xscale/ixp425/ixp425_pci.c
index 9fb5a74..9b10600 100644
--- a/sys/arm/xscale/ixp425/ixp425_pci.c
+++ b/sys/arm/xscale/ixp425/ixp425_pci.c
@@ -276,12 +276,10 @@ static struct resource *
ixppcib_alloc_resource(device_t bus, device_t child, int type, int *rid,
u_long start, u_long end, u_long count, u_int flags)
{
- bus_space_tag_t tag;
struct ixppcib_softc *sc = device_get_softc(bus);
struct rman *rmanp;
struct resource *rv;
- tag = NULL; /* shut up stupid gcc */
rv = NULL;
switch (type) {
case SYS_RES_IRQ:
@@ -290,28 +288,25 @@ ixppcib_alloc_resource(device_t bus, device_t child, int type, int *rid,
case SYS_RES_IOPORT:
rmanp = &sc->sc_io_rman;
- tag = &sc->sc_pci_iot;
break;
case SYS_RES_MEMORY:
rmanp = &sc->sc_mem_rman;
- tag = &sc->sc_pci_memt;
break;
default:
return (rv);
}
- rv = rman_reserve_resource(rmanp, start, end, count, flags, child);
- if (rv != NULL) {
- rman_set_rid(rv, *rid);
- if (type == SYS_RES_IOPORT) {
- rman_set_bustag(rv, tag);
- rman_set_bushandle(rv, rman_get_start(rv));
- } else if (type == SYS_RES_MEMORY) {
- rman_set_bustag(rv, tag);
- rman_set_bushandle(rv, rman_get_bushandle(sc->sc_mem) +
- (rman_get_start(rv) - IXP425_PCI_MEM_HWBASE));
+ rv = rman_reserve_resource(rmanp, start, end, count, flags & ~RF_ACTIVE,
+ child);
+ if (rv == NULL)
+ return (NULL);
+ rman_set_rid(rv, *rid);
+ if (flags & RF_ACTIVE) {
+ if (bus_activate_resource(child, type, *rid, rv)) {
+ rman_release_resource(rv);
+ return (NULL);
}
}
@@ -323,9 +318,21 @@ ixppcib_activate_resource(device_t bus, device_t child, int type, int rid,
struct resource *r)
{
- device_printf(bus, "%s called activate_resource (unexpected)\n",
- device_get_nameunit(child));
- return (ENXIO);
+ struct ixppcib_softc *sc = device_get_softc(bus);
+
+ switch (type) {
+ case SYS_RES_IOPORT:
+ rman_set_bustag(r, &sc->sc_pci_iot);
+ rman_set_bushandle(r, rman_get_start(r));
+ break;
+ case SYS_RES_MEMORY:
+ rman_set_bustag(r, &sc->sc_pci_memt);
+ rman_set_bushandle(r, rman_get_bushandle(sc->sc_mem) +
+ (rman_get_start(r) - IXP425_PCI_MEM_HWBASE));
+ break;
+ }
+
+ return (rman_activate_resource(r));
}
static int
OpenPOWER on IntegriCloud