Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/fdt Attach devices in order of "phandle" property in...
details: https://anonhg.NetBSD.org/src/rev/7c3450ce99ba
branches: trunk
changeset: 823206:7c3450ce99ba
user: jmcneill <jmcneill%NetBSD.org@localhost>
date: Sun Apr 16 12:24:57 2017 +0000
description:
Attach devices in order of "phandle" property inserted by DTC.
diffstat:
sys/dev/fdt/fdtbus.c | 137 +++++++++++++++++++++++++++++++++-----------------
sys/dev/fdt/fdtvar.h | 5 +-
2 files changed, 91 insertions(+), 51 deletions(-)
diffs (253 lines):
diff -r 8af1e95735b9 -r 7c3450ce99ba sys/dev/fdt/fdtbus.c
--- a/sys/dev/fdt/fdtbus.c Sun Apr 16 12:22:18 2017 +0000
+++ b/sys/dev/fdt/fdtbus.c Sun Apr 16 12:24:57 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: fdtbus.c,v 1.7 2017/04/15 00:34:29 jmcneill Exp $ */
+/* $NetBSD: fdtbus.c,v 1.8 2017/04/16 12:24:57 jmcneill Exp $ */
/*-
* Copyright (c) 2015 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: fdtbus.c,v 1.7 2017/04/15 00:34:29 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fdtbus.c,v 1.8 2017/04/16 12:24:57 jmcneill Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -43,24 +43,33 @@
#define FDT_MAX_PATH 256
struct fdt_node {
+ device_t n_bus;
device_t n_dev;
int n_phandle;
char *n_name;
+ u_int n_order;
+
TAILQ_ENTRY(fdt_node) n_nodes;
};
+static TAILQ_HEAD(, fdt_node) fdt_nodes =
+ TAILQ_HEAD_INITIALIZER(fdt_nodes);
+
struct fdt_softc {
device_t sc_dev;
int sc_phandle;
struct fdt_attach_args sc_faa;
-
- TAILQ_HEAD(, fdt_node) sc_nodes;
};
static int fdt_match(device_t, cfdata_t, void *);
static void fdt_attach(device_t, device_t, void *);
-static void fdt_scan(struct fdt_softc *, const char *, bool);
+static void fdt_scan_bus(struct fdt_softc *);
+static void fdt_scan(struct fdt_softc *);
+static void fdt_add_node(struct fdt_node *);
+static u_int fdt_get_order(int);
+
+static int fdt_print(void *, const char *);
static const char * const fdtbus_compatible[] =
{ "simple-bus", NULL };
@@ -68,17 +77,12 @@
CFATTACH_DECL_NEW(fdt, sizeof(struct fdt_softc),
fdt_match, fdt_attach, NULL, NULL);
-static int fdt_print(void *, const char *);
-
static int
fdt_match(device_t parent, cfdata_t cf, void *aux)
{
const struct fdt_attach_args *faa = aux;
int match;
- if (!OF_child(faa->faa_phandle))
- return 0;
-
match = of_match_compatible(faa->faa_phandle, fdtbus_compatible);
if (match)
return match;
@@ -94,12 +98,11 @@
const int phandle = faa->faa_phandle;
struct fdt_node *node;
char *model, *name, *status;
- int len, n, child;
+ int len, child;
sc->sc_dev = self;
- sc->sc_phandle = faa->faa_phandle;
+ sc->sc_phandle = phandle;
sc->sc_faa = *faa;
- TAILQ_INIT(&sc->sc_nodes);
aprint_naive("\n");
len = OF_getproplen(phandle, "model");
@@ -141,71 +144,111 @@
/* 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;
- TAILQ_INSERT_TAIL(&sc->sc_nodes, node, n_nodes);
+ node->n_order = fdt_get_order(node->n_phandle);
+ fdt_add_node(node);
}
/* Scan and attach all known busses in the tree. */
- for (n = 0; fdtbus_compatible[n] != NULL; n++)
- fdt_scan(sc, fdtbus_compatible[n], true);
+ fdt_scan_bus(sc);
/* Only the root bus should scan for devices */
if (OF_finddevice("/") != faa->faa_phandle)
return;
- /* Scan the tree for "early init" devices */
- for (n = 0; n < faa->faa_ninit; n++)
- fdt_scan(sc, faa->faa_init[n], false);
-
- /* Finally, scan the tree for all other devices */
- fdt_scan(sc, NULL, false);
+ /* Scan devices */
+ fdt_scan(sc);
}
static void
-fdt_scan(struct fdt_softc *sc, const char *compat, bool bus)
+fdt_init_attach_args(struct fdt_softc *sc, struct fdt_node *node,
+ struct fdt_attach_args *faa)
+{
+ *faa = sc->sc_faa;
+ faa->faa_phandle = node->n_phandle;
+ faa->faa_name = node->n_name;
+}
+
+static void
+fdt_scan_bus(struct fdt_softc *sc)
{
struct fdt_node *node;
struct fdt_attach_args faa;
cfdata_t cf;
- TAILQ_FOREACH(node, &sc->sc_nodes, n_nodes) {
- if (node->n_dev != NULL) {
- /*
- * Child is already attached. If it is a bus,
- * recursively scan.
- */
- if (device_is_a(node->n_dev, "fdt"))
- fdt_scan(device_private(node->n_dev), compat,
- bus);
+ TAILQ_FOREACH(node, &fdt_nodes, n_nodes) {
+ if (node->n_bus != sc->sc_dev)
continue;
- }
+ if (node->n_dev != NULL)
+ continue;
- faa = sc->sc_faa;
- faa.faa_phandle = node->n_phandle;
- faa.faa_name = node->n_name;
+ fdt_init_attach_args(sc, node, &faa);
/*
* Only attach busses to nodes where this driver is the best
* match.
*/
- if (compat && bus) {
- cf = config_search_loc(NULL, sc->sc_dev, NULL, NULL,
- &faa);
- if (cf == NULL || strcmp(cf->cf_name, "fdt") != 0)
- continue;
- }
+ cf = config_search_loc(NULL, node->n_bus, NULL, NULL, &faa);
+ if (cf == NULL || strcmp(cf->cf_name, "fdt") != 0)
+ continue;
+
+ /*
+ * Attach the bus.
+ */
+ node->n_dev = config_found(node->n_bus, &faa, fdt_print);
+ }
+}
+
+static void
+fdt_scan(struct fdt_softc *sc)
+{
+ struct fdt_node *node;
+ struct fdt_attach_args faa;
+
+ TAILQ_FOREACH(node, &fdt_nodes, n_nodes) {
+ if (node->n_dev != NULL)
+ continue;
+
+ fdt_init_attach_args(sc, node, &faa);
/*
- * Attach the child device.
+ * Attach the device.
*/
- const char * const compats[] = { compat, NULL };
- if (compat == NULL ||
- of_match_compatible(node->n_phandle, compats)) {
- node->n_dev = config_found(sc->sc_dev, &faa, fdt_print);
+ node->n_dev = config_found(node->n_bus, &faa, fdt_print);
+ }
+}
+
+static void
+fdt_add_node(struct fdt_node *new_node)
+{
+ struct fdt_node *node;
+
+ TAILQ_FOREACH(node, &fdt_nodes, n_nodes)
+ if (node->n_order > new_node->n_order) {
+ TAILQ_INSERT_BEFORE(node, new_node, n_nodes);
+ return;
}
+ TAILQ_INSERT_TAIL(&fdt_nodes, new_node, n_nodes);
+}
+
+static u_int
+fdt_get_order(int phandle)
+{
+ u_int val = UINT_MAX;
+ int child;
+
+ of_getprop_uint32(phandle, "phandle", &val);
+
+ for (child = OF_child(phandle); child; child = OF_peer(child)) {
+ u_int child_val = fdt_get_order(child);
+ if (child_val < val)
+ val = child_val;
}
+
+ return val;
}
static int
diff -r 8af1e95735b9 -r 7c3450ce99ba sys/dev/fdt/fdtvar.h
--- a/sys/dev/fdt/fdtvar.h Sun Apr 16 12:22:18 2017 +0000
+++ b/sys/dev/fdt/fdtvar.h Sun Apr 16 12:24:57 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: fdtvar.h,v 1.8 2017/04/13 22:12:53 jmcneill Exp $ */
+/* $NetBSD: fdtvar.h,v 1.9 2017/04/16 12:24:57 jmcneill Exp $ */
/*-
* Copyright (c) 2015 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -43,9 +43,6 @@
bus_space_tag_t faa_a4x_bst;
bus_dma_tag_t faa_dmat;
int faa_phandle;
-
- const char **faa_init;
- int faa_ninit;
};
/* flags for fdtbus_intr_establish */
Home |
Main Index |
Thread Index |
Old Index