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