From 5063ced278e0093bdf926bc832a804f09fd3bd66 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 30 Jul 2022 15:52:06 -0600 Subject: dm: core: Split out the declaration of ofnode This is used by a lot of files, but ofnode.h needs to include a lot of header files. This can create dependency cycles, particularly with global_data.h which must include various declarations. Split the core delcarations into a separate file to fix this. Signed-off-by: Simon Glass --- include/dm/ofnode.h | 61 +---------------------------------------------------- 1 file changed, 1 insertion(+), 60 deletions(-) (limited to 'include/dm/ofnode.h') diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h index bb60433124b..346b09c7d96 100644 --- a/include/dm/ofnode.h +++ b/include/dm/ofnode.h @@ -19,41 +19,7 @@ struct resource; -/** - * typedef union ofnode_union ofnode - reference to a device tree node - * - * This union can hold either a straightforward pointer to a struct device_node - * in the live device tree, or an offset within the flat device tree. In the - * latter case, the pointer value is just the integer offset within the flat DT. - * - * Thus we can reference nodes in both the live tree (once available) and the - * flat tree (until then). Functions are available to translate between an - * ofnode and either an offset or a `struct device_node *`. - * - * The reference can also hold a null offset, in which case the pointer value - * here is NULL. This corresponds to a struct device_node * value of - * NULL, or an offset of -1. - * - * There is no ambiguity as to whether ofnode holds an offset or a node - * pointer: when the live tree is active it holds a node pointer, otherwise it - * holds an offset. The value itself does not need to be unique and in theory - * the same value could point to a valid device node or a valid offset. We - * could arrange for a unique value to be used (e.g. by making the pointer - * point to an offset within the flat device tree in the case of an offset) but - * this increases code size slightly due to the subtraction. Since it offers no - * real benefit, the approach described here seems best. - * - * For now these points use constant types, since we don't allow writing - * the DT. - * - * @np: Pointer to device node, used for live tree - * @of_offset: Pointer into flat device tree, used for flat tree. Note that this - * is not a really a pointer to a node: it is an offset value. See above. - */ -typedef union ofnode_union { - const struct device_node *np; - long of_offset; -} ofnode; +#include struct ofnode_phandle_args { ofnode node; @@ -61,31 +27,6 @@ struct ofnode_phandle_args { uint32_t args[OF_MAX_PHANDLE_ARGS]; }; -/** - * struct ofprop - reference to a property of a device tree node - * - * This struct hold the reference on one property of one node, - * using struct ofnode and an offset within the flat device tree or either - * a pointer to a struct property in the live device tree. - * - * Thus we can reference arguments in both the live tree and the flat tree. - * - * The property reference can also hold a null reference. This corresponds to - * a struct property NULL pointer or an offset of -1. - * - * @node: Pointer to device node - * @offset: Pointer into flat device tree, used for flat tree. - * @prop: Pointer to property, used for live treee. - */ - -struct ofprop { - ofnode node; - union { - int offset; - const struct property *prop; - }; -}; - /** * ofnode_to_np() - convert an ofnode to a live DT node pointer * -- cgit v1.2.3 From 72b338aa2cd4afff8e92ab28199bc2db073cfea7 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 30 Jul 2022 15:52:07 -0600 Subject: dm: core: Add a note about how livetree updates work The unflattening algorithm results in a single block of memory being allocated for the whole tree. When writing new properties, these are allocated new memory outside that block. When the block is freed, the allocated properties remain. Document how this works and the potential memory leak, as well as mentioning that updating the livetree is actually supported now. Signed-off-by: Simon Glass --- include/dm/ofnode.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include/dm/ofnode.h') diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h index 346b09c7d96..5a5309d79a7 100644 --- a/include/dm/ofnode.h +++ b/include/dm/ofnode.h @@ -1081,7 +1081,8 @@ int ofnode_device_is_compatible(ofnode node, const char *compat); * ofnode_write_prop() - Set a property of a ofnode * * Note that the value passed to the function is *not* allocated by the - * function itself, but must be allocated by the caller if necessary. + * function itself, but must be allocated by the caller if necessary. However + * it does allocate memory for the property struct and name. * * @node: The node for whose property should be set * @propname: The name of the property to set -- cgit v1.2.3 From 331048471dee5c1d9cede54382256e6cfaee2370 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 30 Jul 2022 15:52:08 -0600 Subject: 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 --- include/dm/ofnode.h | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'include/dm/ofnode.h') 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 @@ -176,6 +176,23 @@ static inline ofnode ofnode_root(void) return node; } +/** + * 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,11 +657,22 @@ 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 * -- cgit v1.2.3 From be0789a8ee024e685f070dbd8c58736ea3891654 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 30 Jul 2022 15:52:10 -0600 Subject: dm: core: Swap parameters of ofnode_write_prop() It is normal for the length to come after the value in libfdt. Follow this same convention with ofnode. Signed-off-by: Simon Glass --- include/dm/ofnode.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'include/dm/ofnode.h') diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h index d7ad5dccc14..071a9d63f67 100644 --- a/include/dm/ofnode.h +++ b/include/dm/ofnode.h @@ -1114,13 +1114,13 @@ int ofnode_device_is_compatible(ofnode node, const char *compat); * * @node: The node for whose property should be set * @propname: The name of the property to set - * @len: The length of the new value of the property * @value: The new value of the property (must be valid prior to calling * the function) + * @len: The length of the new value of the property * Return: 0 if successful, -ve on error */ -int ofnode_write_prop(ofnode node, const char *propname, int len, - const void *value); +int ofnode_write_prop(ofnode node, const char *propname, const void *value, + int len); /** * ofnode_write_string() - Set a string property of a ofnode -- cgit v1.2.3 From 39e42be12b9456e604ac3e228973b1cb1136864c Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 30 Jul 2022 15:52:13 -0600 Subject: dm: core: Allow writing to a flat tree with ofnode In generally it is not permitted to implement an ofnode function only for flat tree or live tree. Both must be supported. Also the code for live tree access should be in of_access.c rather than ofnode.c which is really just for holding the API-conversion code. Update ofnode_write_prop() accordingly and fix the test so it can work with flat tree too. Signed-off-by: Simon Glass --- include/dm/ofnode.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'include/dm/ofnode.h') diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h index 071a9d63f67..16c8890b097 100644 --- a/include/dm/ofnode.h +++ b/include/dm/ofnode.h @@ -44,6 +44,24 @@ static inline const struct device_node *ofnode_to_np(ofnode node) return node.np; } +/** + * ofnode_to_npw() - convert an ofnode to a writeable live DT node pointer + * + * This cannot be called if the reference contains an offset. + * + * @node: Reference containing struct device_node * (possibly invalid) + * Return: pointer to device node (can be NULL) + */ +static inline struct device_node *ofnode_to_npw(ofnode node) +{ +#ifdef OF_CHECKS + if (!of_live_active()) + return NULL; +#endif + /* Drop constant */ + return (struct device_node *)node.np; +} + /** * ofnode_to_offset() - convert an ofnode to a flat DT offset * -- cgit v1.2.3 From 55f7990bfeb92c172065d5b53c59d5306cc554ca Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 30 Jul 2022 15:52:14 -0600 Subject: dm: core: Add support for writing u32 with ofnode Add a new function to write an integer to an ofnode (live tree or flat tree). Signed-off-by: Simon Glass --- include/dm/ofnode.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'include/dm/ofnode.h') diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h index 16c8890b097..7ce1e4c6d91 100644 --- a/include/dm/ofnode.h +++ b/include/dm/ofnode.h @@ -1154,6 +1154,16 @@ int ofnode_write_prop(ofnode node, const char *propname, const void *value, */ int ofnode_write_string(ofnode node, const char *propname, const char *value); +/** + * ofnode_write_u32() - Set an integer property of an ofnode + * + * @node: The node for whose string property should be set + * @propname: The name of the string property to set + * @value: The new value of the 32-bit integer property + * Return: 0 if successful, -ve on error + */ +int ofnode_write_u32(ofnode node, const char *propname, u32 value); + /** * ofnode_set_enabled() - Enable or disable a device tree node given by its * ofnode -- cgit v1.2.3