summaryrefslogtreecommitdiff
path: root/sys/dev/fdt
diff options
context:
space:
mode:
authorjmcneill <jmcneill@NetBSD.org>2018-06-30 16:22:56 +0000
committerjmcneill <jmcneill@NetBSD.org>2018-06-30 16:22:56 +0000
commit7f828f6d436b53ef3bbbc4e2ccc746c0919cb571 (patch)
tree4a0bc7745ac1164a4ffe00041e052ee7a95566f7 /sys/dev/fdt
parent0d05a8b86d128ab1e688689a93b76f24b40310ab (diff)
Allow nodes to attach child devices using the same sorting rules as used
by the simplebus driver.
Diffstat (limited to 'sys/dev/fdt')
-rw-r--r--sys/dev/fdt/fdtbus.c108
-rw-r--r--sys/dev/fdt/fdtvar.h4
-rw-r--r--sys/dev/fdt/files.fdt48
-rw-r--r--sys/dev/fdt/syscon.c6
4 files changed, 91 insertions, 75 deletions
diff --git a/sys/dev/fdt/fdtbus.c b/sys/dev/fdt/fdtbus.c
index d2f31246294..2f71e133ac7 100644
--- a/sys/dev/fdt/fdtbus.c
+++ b/sys/dev/fdt/fdtbus.c
@@ -1,4 +1,4 @@
-/* $NetBSD: fdtbus.c,v 1.20 2018/06/30 13:44:50 jmcneill Exp $ */
+/* $NetBSD: fdtbus.c,v 1.21 2018/06/30 16:22:56 jmcneill Exp $ */
/*-
* Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca>
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: fdtbus.c,v 1.20 2018/06/30 13:44:50 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fdtbus.c,v 1.21 2018/06/30 16:22:56 jmcneill Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -50,7 +50,8 @@ struct fdt_node {
device_t n_bus;
device_t n_dev;
int n_phandle;
- char *n_name;
+ const char *n_name;
+ struct fdt_attach_args n_faa;
u_int n_order;
@@ -59,6 +60,7 @@ struct fdt_node {
static TAILQ_HEAD(, fdt_node) fdt_nodes =
TAILQ_HEAD_INITIALIZER(fdt_nodes);
+static bool fdt_need_rescan = false;
struct fdt_softc {
device_t sc_dev;
@@ -69,7 +71,7 @@ struct fdt_softc {
static int fdt_match(device_t, cfdata_t, void *);
static void fdt_attach(device_t, device_t, void *);
static int fdt_scan_submatch(device_t, cfdata_t, const int *, void *);
-static void fdt_scan_bus(struct fdt_softc *);
+static void fdt_scan_bus(device_t, const int);
static void fdt_scan(struct fdt_softc *, int);
static void fdt_add_node(struct fdt_node *);
static u_int fdt_get_order(int);
@@ -77,7 +79,7 @@ static u_int fdt_get_order(int);
static const char * const fdtbus_compatible[] =
{ "simple-bus", "simple-mfd", NULL };
-CFATTACH_DECL_NEW(fdt, sizeof(struct fdt_softc),
+CFATTACH_DECL_NEW(simplebus, sizeof(struct fdt_softc),
fdt_match, fdt_attach, NULL, NULL);
static int
@@ -111,51 +113,25 @@ fdt_attach(device_t parent, device_t self, void *aux)
const struct fdt_attach_args *faa = aux;
const int phandle = faa->faa_phandle;
struct fdt_node *node;
- char *model, *name;
- int len, child;
+ const char *model;
+ int pass;
sc->sc_dev = self;
sc->sc_phandle = phandle;
sc->sc_faa = *faa;
aprint_naive("\n");
- len = OF_getproplen(phandle, "model");
- if (len > 0) {
- model = kmem_zalloc(len, KM_SLEEP);
- if (OF_getprop(phandle, "model", model, len) == len) {
- aprint_normal(": %s\n", model);
- } else {
- aprint_normal("\n");
- }
- kmem_free(model, len);
- } else {
+ model = fdtbus_get_string(phandle, "model");
+ if (model)
+ aprint_normal(": %s\n", model);
+ else
aprint_normal("\n");
- }
-
- for (child = OF_child(phandle); child; child = OF_peer(child)) {
- if (!fdtbus_status_okay(child))
- continue;
- len = OF_getproplen(child, "name");
- if (len <= 0)
- continue;
-
- name = kmem_zalloc(len, KM_SLEEP);
- if (OF_getprop(child, "name", name, len) != len)
- continue;
-
- /* Add the node to our device list */
- node = kmem_alloc(sizeof(*node), KM_SLEEP);
- node->n_bus = self;
- node->n_dev = NULL;
- node->n_phandle = child;
- node->n_name = name;
- node->n_order = fdt_get_order(node->n_phandle);
- fdt_add_node(node);
- }
+ /* Find all child nodes */
+ fdt_add_bus(self, phandle, &sc->sc_faa);
/* Scan and attach all known busses in the tree. */
- fdt_scan_bus(sc);
+ fdt_scan_bus(self, phandle);
/* Only the root bus should scan for devices */
if (OF_finddevice("/") != faa->faa_phandle)
@@ -174,34 +150,44 @@ fdt_attach(device_t parent, device_t self, void *aux)
}
/* Scan devices */
- for (int pass = 0; pass <= FDTCF_PASS_DEFAULT; pass++)
+ pass = 0;
+ fdt_need_rescan = false;
+ do {
fdt_scan(sc, pass);
+ if (fdt_need_rescan == true) {
+ pass = 0;
+ fdt_need_rescan = false;
+ } else {
+ pass++;
+ }
+ } while (pass <= FDTCF_PASS_DEFAULT);
}
static void
-fdt_init_attach_args(struct fdt_softc *sc, struct fdt_node *node,
+fdt_init_attach_args(const struct fdt_attach_args *faa_tmpl, struct fdt_node *node,
bool quiet, struct fdt_attach_args *faa)
{
- *faa = sc->sc_faa;
+ *faa = *faa_tmpl;
faa->faa_phandle = node->n_phandle;
faa->faa_name = node->n_name;
faa->faa_quiet = quiet;
}
static void
-fdt_scan_bus(struct fdt_softc *sc)
+fdt_scan_bus(device_t bus, const int phandle)
{
struct fdt_node *node;
struct fdt_attach_args faa;
cfdata_t cf;
TAILQ_FOREACH(node, &fdt_nodes, n_nodes) {
- if (node->n_bus != sc->sc_dev)
+ if (node->n_bus != bus)
continue;
if (node->n_dev != NULL)
continue;
- fdt_init_attach_args(sc, node, true, &faa);
+ faa = node->n_faa;
+ faa.faa_quiet = true;
/*
* Only attach busses to nodes where this driver is the best
@@ -218,6 +204,32 @@ fdt_scan_bus(struct fdt_softc *sc)
}
}
+void
+fdt_add_bus(device_t bus, const int phandle, struct fdt_attach_args *faa)
+{
+ struct fdt_node *node;
+ int child;
+
+ for (child = OF_child(phandle); child; child = OF_peer(child)) {
+ if (!fdtbus_status_okay(child))
+ continue;
+
+ /* Add the node to our device list */
+ node = kmem_alloc(sizeof(*node), KM_SLEEP);
+ node->n_bus = bus;
+ node->n_dev = NULL;
+ node->n_phandle = child;
+ node->n_name = fdtbus_get_string(child, "name");
+ node->n_order = fdt_get_order(child);
+ node->n_faa = *faa;
+ node->n_faa.faa_phandle = child;
+ node->n_faa.faa_name = node->n_name;
+
+ fdt_add_node(node);
+ fdt_need_rescan = true;
+ }
+}
+
static int
fdt_scan_submatch(device_t parent, cfdata_t cf, const int *locs, void *aux)
{
@@ -242,7 +254,7 @@ fdt_scan_best(struct fdt_softc *sc, struct fdt_node *node)
const int locs[FDTCF_NLOCS] = {
[FDTCF_PASS] = pass
};
- fdt_init_attach_args(sc, node, true, &faa);
+ fdt_init_attach_args(&sc->sc_faa, node, true, &faa);
cf = config_search_loc(fdt_scan_submatch, node->n_bus, "fdt", locs, &faa);
if (cf == NULL)
continue;
@@ -270,7 +282,7 @@ fdt_scan(struct fdt_softc *sc, int pass)
if (node->n_dev != NULL)
continue;
- fdt_init_attach_args(sc, node, quiet, &faa);
+ fdt_init_attach_args(&sc->sc_faa, node, quiet, &faa);
/*
* Make sure we don't attach before a better match in a later pass.
diff --git a/sys/dev/fdt/fdtvar.h b/sys/dev/fdt/fdtvar.h
index 502195114b4..80b59a457d1 100644
--- a/sys/dev/fdt/fdtvar.h
+++ b/sys/dev/fdt/fdtvar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: fdtvar.h,v 1.35 2018/06/30 12:35:18 jmcneill Exp $ */
+/* $NetBSD: fdtvar.h,v 1.36 2018/06/30 16:22:56 jmcneill Exp $ */
/*-
* Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca>
@@ -351,6 +351,8 @@ const void * fdtbus_get_prop(int, const char *, int *);
const char * fdtbus_get_string(int, const char *);
const char * fdtbus_get_string_index(int, const char *, u_int);
+void fdt_add_bus(device_t, int, struct fdt_attach_args *);
+
void fdt_remove_byhandle(int);
void fdt_remove_bycompat(const char *[]);
int fdtbus_print(void *, const char *);
diff --git a/sys/dev/fdt/files.fdt b/sys/dev/fdt/files.fdt
index 9116555977a..05b009661db 100644
--- a/sys/dev/fdt/files.fdt
+++ b/sys/dev/fdt/files.fdt
@@ -1,13 +1,13 @@
-# $NetBSD: files.fdt,v 1.34 2018/06/30 12:35:18 jmcneill Exp $
+# $NetBSD: files.fdt,v 1.35 2018/06/30 16:22:56 jmcneill Exp $
include "external/bsd/libfdt/conf/files.libfdt"
defflag opt_fdt.h FDT: libfdt, ofw_subr
-define fdtbus { } : clk, pwm
+define fdt { [pass = 10] } : clk, pwm
-device fdt { [pass = 10] } : fdtbus
-attach fdt at fdtbus
+device simplebus { } : fdt
+attach simplebus at fdt
file dev/fdt/fdtbus.c fdt
device fregulator
@@ -44,25 +44,25 @@ device panel: fdt_port
attach panel at fdt with fdt_panel
file dev/fdt/panel_fdt.c fdt_panel
-file dev/fdt/fdt_openfirm.c fdtbus
-file dev/fdt/fdt_subr.c fdtbus
-file dev/fdt/fdt_clock.c fdtbus
-file dev/fdt/fdt_dai.c fdtbus
-file dev/fdt/fdt_dma.c fdtbus
-file dev/fdt/fdt_gpio.c fdtbus
-file dev/fdt/fdt_i2c.c fdtbus
-file dev/fdt/fdt_intr.c fdtbus
-file dev/fdt/fdt_mmc_pwrseq.c fdtbus
-file dev/fdt/fdt_phy.c fdtbus
-file dev/fdt/fdt_power.c fdtbus
-file dev/fdt/fdt_pwm.c fdtbus
-file dev/fdt/fdt_regulator.c fdtbus
-file dev/fdt/fdt_reset.c fdtbus
-file dev/fdt/fdt_rtc.c fdtbus
-file dev/fdt/fdt_syscon.c fdtbus
-file dev/fdt/fdt_pinctrl.c fdtbus
-
-device cpus { } : fdtbus
+file dev/fdt/fdt_openfirm.c fdt
+file dev/fdt/fdt_subr.c fdt
+file dev/fdt/fdt_clock.c fdt
+file dev/fdt/fdt_dai.c fdt
+file dev/fdt/fdt_dma.c fdt
+file dev/fdt/fdt_gpio.c fdt
+file dev/fdt/fdt_i2c.c fdt
+file dev/fdt/fdt_intr.c fdt
+file dev/fdt/fdt_mmc_pwrseq.c fdt
+file dev/fdt/fdt_phy.c fdt
+file dev/fdt/fdt_power.c fdt
+file dev/fdt/fdt_pwm.c fdt
+file dev/fdt/fdt_regulator.c fdt
+file dev/fdt/fdt_reset.c fdt
+file dev/fdt/fdt_rtc.c fdt
+file dev/fdt/fdt_syscon.c fdt
+file dev/fdt/fdt_pinctrl.c fdt
+
+device cpus { } : fdt
attach cpus at fdt
file dev/fdt/cpus.c cpus
@@ -70,7 +70,7 @@ device mmcpwrseq
attach mmcpwrseq at fdt
file dev/fdt/mmc_pwrseq_simple.c mmcpwrseq
-device syscon
+device syscon { } : fdt
attach syscon at fdt
file dev/fdt/syscon.c syscon
diff --git a/sys/dev/fdt/syscon.c b/sys/dev/fdt/syscon.c
index e902cc87237..cbfaaeb53c7 100644
--- a/sys/dev/fdt/syscon.c
+++ b/sys/dev/fdt/syscon.c
@@ -1,4 +1,4 @@
-/* $NetBSD: syscon.c,v 1.1 2018/06/30 12:35:18 jmcneill Exp $ */
+/* $NetBSD: syscon.c,v 1.2 2018/06/30 16:22:56 jmcneill Exp $ */
/*-
* Copyright (c) 2018 Jared McNeill <jmcneill@invisible.ca>
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: syscon.c,v 1.1 2018/06/30 12:35:18 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: syscon.c,v 1.2 2018/06/30 16:22:56 jmcneill Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -135,4 +135,6 @@ syscon_attach(device_t parent, device_t self, void *aux)
aprint_normal(": System Controller Registers\n");
fdtbus_register_syscon(self, phandle, &sc->sc_syscon);
+
+ fdt_add_bus(self, phandle, faa);
}