diff options
author | Simon Glass | 2022-09-06 20:27:26 -0600 |
---|---|---|
committer | Tom Rini | 2022-09-29 22:43:43 -0400 |
commit | 92291652b5741647919770c29cae8a2aac56b2bf (patch) | |
tree | 00a4c98a315009b10ac11079d52d70975d3caeef /include/dm/ofnode.h | |
parent | 41b65d68ec324d9c75dcfe6e1b34fef077b4b87a (diff) |
dm: core: Add the ofnode multi-tree implementation
Add the logic to redirect requests for the device tree through a function
which can look up the tree ID. This works by using the top bits of
ofnode.of_offset to encode a tree.
It is assumed that there will only be a few device trees used at runtime,
typically the control FDT (always tree ID 0) and possibly a separate FDT
to be passed the OS.
The maximum number of device trees supported at runtime is 8, with this
implementation. That would use bits 30:28 of the node-offset value,
meaning that the positive offset range is limited to bits 27:0, versus
30:1 with this feature disabled. That still allows a device tree of up
to 256MB, which should be enough for most FITs. Larger ones can be
supported by using external data with the FIT, or by enabling OF_LIVE.
Update the documentation a little and fix up the comment for
ofnode_valid().
Signed-off-by: Simon Glass <sjg@chromium.org>
Diffstat (limited to 'include/dm/ofnode.h')
-rw-r--r-- | include/dm/ofnode.h | 111 |
1 files changed, 64 insertions, 47 deletions
diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h index ad179a65e97..3a514f71f6b 100644 --- a/include/dm/ofnode.h +++ b/include/dm/ofnode.h @@ -27,13 +27,14 @@ struct ofnode_phandle_args { uint32_t args[OF_MAX_PHANDLE_ARGS]; }; +#if CONFIG_IS_ENABLED(OFNODE_MULTI_TREE) /** * oftree_reset() - reset the state of the oftree list * * Reset the oftree list so it can be started again. This should be called * once the control FDT is in place, but before the ofnode interface is used. */ -static inline void oftree_reset(void) {} +void oftree_reset(void); /** * ofnode_to_fdt() - convert an ofnode to a flat DT pointer @@ -43,26 +44,50 @@ static inline void oftree_reset(void) {} * @node: Reference containing offset (possibly invalid) * Return: DT offset (can be NULL) */ +__attribute_const__ void *ofnode_to_fdt(ofnode node); + +/** + * ofnode_to_offset() - convert an ofnode to a flat DT offset + * + * This cannot be called if the reference contains a node pointer. + * + * @node: Reference containing offset (possibly invalid) + * Return: DT offset (can be -1) + */ +__attribute_const__ int ofnode_to_offset(ofnode node); + +/** + * oftree_from_fdt() - Returns an oftree from a flat device tree pointer + * + * @fdt: Device tree to use + * + * Returns: reference to the given node + */ +oftree oftree_from_fdt(void *fdt); + +/** + * noffset_to_ofnode() - convert a DT offset to an ofnode + * + * @other_node: Node in the same tree to use as a reference + * @of_offset: DT offset (either valid, or -1) + * Return: reference to the associated DT offset + */ +ofnode noffset_to_ofnode(ofnode other_node, int of_offset); + +#else /* !OFNODE_MULTI_TREE */ +static inline void oftree_reset(void) {} + static inline void *ofnode_to_fdt(ofnode node) { #ifdef OF_CHECKS if (of_live_active()) return NULL; #endif - /* Use the control FDT by default */ return (void *)gd->fdt_blob; } -/** - * ofnode_to_offset() - convert an ofnode to a flat DT offset - * - * This cannot be called if the reference contains a node pointer. - * - * @node: Reference containing offset (possibly invalid) - * Return: DT offset (can be -1) - */ -static inline int ofnode_to_offset(ofnode node) +static inline __attribute_const__ int ofnode_to_offset(ofnode node) { #ifdef OF_CHECKS if (of_live_active()) @@ -71,6 +96,33 @@ static inline int ofnode_to_offset(ofnode node) return node.of_offset; } +static inline oftree oftree_from_fdt(void *fdt) +{ + oftree tree; + + /* we cannot access other trees without OFNODE_MULTI_TREE */ + if (fdt == gd->fdt_blob) + tree.fdt = fdt; + else + tree.fdt = NULL; + + return tree; +} + +static inline ofnode noffset_to_ofnode(ofnode other_node, int of_offset) +{ + ofnode node; + + if (of_live_active()) + node.np = NULL; + else + node.of_offset = of_offset; + + return node; +} + +#endif /* OFNODE_MULTI_TREE */ + /** * ofnode_to_np() - convert an ofnode to a live DT node pointer * @@ -89,29 +141,10 @@ static inline struct device_node *ofnode_to_np(ofnode node) } /** - * noffset_to_ofnode() - convert a DT offset to an ofnode - * - * @other_node: Node in the same tree to use as a reference - * @of_offset: DT offset (either valid, or -1) - * Return: reference to the associated DT offset - */ -static inline ofnode noffset_to_ofnode(ofnode other_node, int of_offset) -{ - ofnode node; - - if (of_live_active()) - node.np = NULL; - else - node.of_offset = of_offset; - - return node; -} - -/** * ofnode_valid() - check if an ofnode is valid * * @node: Reference containing offset (possibly invalid) - * Return: true if the reference contains a valid ofnode, false if it is NULL + * Return: true if the reference contains a valid ofnode, false if not */ static inline bool ofnode_valid(ofnode node) { @@ -317,22 +350,6 @@ static inline oftree oftree_from_np(struct device_node *root) } /** - * oftree_from_fdt() - Returns an oftree from a flat device tree pointer - * - * @fdt: Device tree to use - * - * Returns: reference to the given node - */ -static inline oftree oftree_from_fdt(void *fdt) -{ - oftree tree; - - tree.fdt = fdt; - - return tree; -} - -/** * ofnode_name_eq() - Check if the node name is equivalent to a given name * ignoring the unit address * |