summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Gray <jsg@cvs.openbsd.org>2016-08-06 00:04:40 +0000
committerJonathan Gray <jsg@cvs.openbsd.org>2016-08-06 00:04:40 +0000
commit1f81fe2c5c3eb4b018ca4b28fef2c2823233d632 (patch)
tree4dd69fed2fb663208fae73bba717038c631e7181
parentf6b94fa40501a4f3c1e5b5752b97f2a5c6abc7fb (diff)
Set up the fdt attach args for devices that attach directly to mainbus
the same way as for those that attach to simplebus. ok kettenis@ patrick@
-rw-r--r--sys/arch/arm/mainbus/mainbus.c55
1 files changed, 54 insertions, 1 deletions
diff --git a/sys/arch/arm/mainbus/mainbus.c b/sys/arch/arm/mainbus/mainbus.c
index 4c15f302610..59f9a7bfd9d 100644
--- a/sys/arch/arm/mainbus/mainbus.c
+++ b/sys/arch/arm/mainbus/mainbus.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mainbus.c,v 1.12 2016/08/04 12:17:36 kettenis Exp $ */
+/* $OpenBSD: mainbus.c,v 1.13 2016/08/06 00:04:39 jsg Exp $ */
/*
* Copyright (c) 2016 Patrick Wildt <patrick@blueri.se>
*
@@ -22,6 +22,7 @@
#include <sys/malloc.h>
#include <dev/ofw/openfirm.h>
+#include <dev/ofw/fdt.h>
#include <arm/mainbus/mainbus.h>
@@ -38,6 +39,8 @@ struct mainbus_softc {
bus_dma_tag_t sc_dmat;
int sc_acells;
int sc_scells;
+ int *sc_ranges;
+ int sc_rangeslen;
};
struct cfattach mainbus_ca = {
@@ -122,6 +125,13 @@ mainbus_attach(struct device *parent, struct device *self, void *aux)
/* TODO: Scan for interrupt controllers and attach them first? */
+ sc->sc_rangeslen = OF_getproplen(OF_peer(0), "ranges");
+ if (sc->sc_rangeslen > 0 && !(sc->sc_rangeslen % sizeof(uint32_t))) {
+ sc->sc_ranges = malloc(sc->sc_rangeslen, M_TEMP, M_WAITOK);
+ OF_getpropintarray(OF_peer(0), "ranges", sc->sc_ranges,
+ sc->sc_rangeslen);
+ }
+
/* Scan the whole tree. */
for (node = OF_child(node);
node != 0;
@@ -140,6 +150,8 @@ mainbus_attach_node(struct device *self, int node)
struct mainbus_softc *sc = (struct mainbus_softc *)self;
struct fdt_attach_args fa;
char buffer[128];
+ int i, len, line;
+ uint32_t *cell, *reg;
if (!OF_getprop(node, "compatible", buffer, sizeof(buffer)))
return;
@@ -156,9 +168,50 @@ mainbus_attach_node(struct device *self, int node)
fa.fa_acells = sc->sc_acells;
fa.fa_scells = sc->sc_scells;
+ len = OF_getproplen(node, "reg");
+ line = (sc->sc_acells + sc->sc_scells) * sizeof(uint32_t);
+ if (len > 0 && (len % line) == 0) {
+ reg = malloc(len, M_TEMP, M_WAITOK);
+ OF_getpropintarray(node, "reg", reg, len);
+
+ fa.fa_reg = malloc((len / line) * sizeof(struct fdt_reg),
+ M_DEVBUF, M_WAITOK);
+ fa.fa_nreg = (len / line);
+
+ for (i = 0, cell = reg; i < len / line; i++) {
+ if (sc->sc_acells >= 1)
+ fa.fa_reg[i].addr = cell[0];
+ if (sc->sc_acells == 2) {
+ fa.fa_reg[i].addr <<= 32;
+ fa.fa_reg[i].addr |= cell[1];
+ }
+ cell += sc->sc_acells;
+ if (sc->sc_scells >= 1)
+ fa.fa_reg[i].size = cell[0];
+ if (sc->sc_scells == 2) {
+ fa.fa_reg[i].size <<= 32;
+ fa.fa_reg[i].size |= cell[1];
+ }
+ cell += sc->sc_scells;
+ }
+
+ free(reg, M_TEMP, len);
+ }
+
+ len = OF_getproplen(node, "interrupts");
+ if (len > 0 && (len % sizeof(uint32_t)) == 0) {
+ fa.fa_intr = malloc(len, M_DEVBUF, M_WAITOK);
+ fa.fa_nintr = len / sizeof(uint32_t);
+
+ OF_getpropintarray(node, "interrupts", fa.fa_intr, len);
+ }
+
/* TODO: attach the device's clocks first? */
config_found(self, &fa, NULL);
+
+ free(fa.fa_reg, M_DEVBUF, fa.fa_nreg * sizeof(struct fdt_reg));
+ free(fa.fa_intr, M_DEVBUF, fa.fa_nintr * sizeof(uint32_t));
}
/*