aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorSimon Glass2022-07-30 15:52:08 -0600
committerTom Rini2022-08-12 08:14:23 -0400
commit331048471dee5c1d9cede54382256e6cfaee2370 (patch)
treed12f08911b3f33b1da5ec9970ee1995aef23e6fe /include
parent72b338aa2cd4afff8e92ab28199bc2db073cfea7 (diff)
dm: core: Introduce support for multiple trees
At present ofnode only works with a single device tree, for the most part. This is the control FDT used by U-Boot. When booting an OS we may obtain a different device tree and want to modify it. Add some initial support for this into the ofnode API. Note that we don't permit aliases in this other device tree, since the of_access implementation maintains a list of aliases collected at start-up. Also, we don't need aliases to do fixups in the other FDT. So make sure that flat tree and live tree processing are consistent in this area. Signed-off-by: Simon Glass <sjg@chromium.org>
Diffstat (limited to 'include')
-rw-r--r--include/dm/of_access.h10
-rw-r--r--include/dm/ofnode.h28
-rw-r--r--include/dm/ofnode_decl.h13
-rw-r--r--include/of_live.h16
4 files changed, 65 insertions, 2 deletions
diff --git a/include/dm/of_access.h b/include/dm/of_access.h
index ec6e6e2c7c0..078f2ea06cd 100644
--- a/include/dm/of_access.h
+++ b/include/dm/of_access.h
@@ -197,6 +197,11 @@ struct device_node *of_get_parent(const struct device_node *np);
/**
* of_find_node_opts_by_path() - Find a node matching a full OF path
*
+ * Note that alias processing is only available on the control FDT (gd->of_root).
+ * For other trees it is skipped, so any attempt to obtain an alias will result
+ * in returning NULL.
+ *
+ * @root: Root node of the tree to use. If this is NULL, then gd->of_root is used
* @path: Either the full path to match, or if the path does not start with
* '/', the name of a property of the /aliases node (an alias). In the
* case of an alias, the node matching the alias' value will be returned.
@@ -210,12 +215,13 @@ struct device_node *of_get_parent(const struct device_node *np);
*
* Return: a node pointer or NULL if not found
*/
-struct device_node *of_find_node_opts_by_path(const char *path,
+struct device_node *of_find_node_opts_by_path(struct device_node *root,
+ const char *path,
const char **opts);
static inline struct device_node *of_find_node_by_path(const char *path)
{
- return of_find_node_opts_by_path(path, NULL);
+ return of_find_node_opts_by_path(NULL, path, NULL);
}
/**
diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h
index 5a5309d79a7..d7ad5dccc14 100644
--- a/include/dm/ofnode.h
+++ b/include/dm/ofnode.h
@@ -177,6 +177,23 @@ static inline ofnode ofnode_root(void)
}
/**
+ * oftree_default() - Returns the default device tree (U-Boot's control FDT)
+ *
+ * Returns: reference to the control FDT
+ */
+static inline oftree oftree_default(void)
+{
+ oftree tree;
+
+ if (of_live_active())
+ tree.np = gd_of_root();
+ else
+ tree.fdt = (void *)gd->fdt_blob;
+
+ return tree;
+}
+
+/**
* ofnode_name_eq() - Check if the node name is equivalent to a given name
* ignoring the unit address
*
@@ -640,12 +657,23 @@ int ofnode_count_phandle_with_args(ofnode node, const char *list_name,
/**
* ofnode_path() - find a node by full path
*
+ * This uses the control FDT.
+ *
* @path: Full path to node, e.g. "/bus/spi@1"
* Return: reference to the node found. Use ofnode_valid() to check if it exists
*/
ofnode ofnode_path(const char *path);
/**
+ * ofnode_path_root() - find a node by full path from a root node
+ *
+ * @tree: Device tree to use
+ * @path: Full path to node, e.g. "/bus/spi@1"
+ * Return: reference to the node found. Use ofnode_valid() to check if it exists
+ */
+ofnode ofnode_path_root(oftree tree, const char *path);
+
+/**
* ofnode_read_chosen_prop() - get the value of a chosen property
*
* This looks for a property within the /chosen node and returns its value
diff --git a/include/dm/ofnode_decl.h b/include/dm/ofnode_decl.h
index 7c9e43e4ad8..266253d5e33 100644
--- a/include/dm/ofnode_decl.h
+++ b/include/dm/ofnode_decl.h
@@ -68,5 +68,18 @@ struct ofprop {
};
};
+/**
+ * union oftree_union - reference to a tree of device tree nodes
+ *
+ * One or other of the members is used, depending on of_live_active()
+ *
+ * @np: Pointer to roott device node, used for live tree
+ * @fdt: Pointer to the flat device tree, used for flat tree
+ */
+typedef union oftree_union {
+ struct device_node *np;
+ void *fdt;
+} oftree;
+
#endif
diff --git a/include/of_live.h b/include/of_live.h
index b2b9679ae84..f59d6af3350 100644
--- a/include/of_live.h
+++ b/include/of_live.h
@@ -20,4 +20,20 @@ struct device_node;
*/
int of_live_build(const void *fdt_blob, struct device_node **rootp);
+/**
+ * unflatten_device_tree() - create tree of device_nodes from flat blob
+ *
+ * Note that this allocates a single block of memory, pointed to by *mynodes.
+ * To free the tree, use free(*mynodes)
+ *
+ * unflattens a device-tree, creating the
+ * tree of struct device_node. It also fills the "name" and "type"
+ * pointers of the nodes so the normal device-tree walking functions
+ * can be used.
+ * @blob: The blob to expand
+ * @mynodes: The device_node tree created by the call
+ * Return: 0 if OK, -ve on error
+ */
+int unflatten_device_tree(const void *blob, struct device_node **mynodes);
+
#endif