Add helper to allow searching for subnode path given a base node offset. Behaves the same as fdt_path_offset when offset = 0. Aliases are only allowed when offset == 0. Signed-off-by: Ayush Singh <ayush@xxxxxxxxxxxxxxx> --- libfdt/fdt_ro.c | 17 ++++++++++++++--- libfdt/libfdt.h | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 3 deletions(-) diff --git a/libfdt/fdt_ro.c b/libfdt/fdt_ro.c index b78c4e48f1cb351504af4d861513b47f375262f5..f426183651cff746b67ebfe86e5809325cad4fec 100644 --- a/libfdt/fdt_ro.c +++ b/libfdt/fdt_ro.c @@ -247,11 +247,11 @@ int fdt_subnode_offset(const void *fdt, int parentoffset, return fdt_subnode_offset_namelen(fdt, parentoffset, name, strlen(name)); } -int fdt_path_offset_namelen(const void *fdt, const char *path, int namelen) +static int fdt_relative_path_offset_namelen(const void *fdt, const char *path, + int namelen, size_t offset) { const char *end = path + namelen; const char *p = path; - int offset = 0; FDT_RO_PROBE(fdt); @@ -259,7 +259,7 @@ int fdt_path_offset_namelen(const void *fdt, const char *path, int namelen) return -FDT_ERR_BADPATH; /* see if we have an alias */ - if (*path != '/') { + if (*path != '/' && offset == 0) { const char *q = memchr(path, '/', end - p); if (!q) @@ -295,11 +295,22 @@ int fdt_path_offset_namelen(const void *fdt, const char *path, int namelen) return offset; } +int fdt_path_offset_namelen(const void *fdt, const char *path, int namelen) +{ + return fdt_relative_path_offset_namelen(fdt, path, namelen, 0); +} + int fdt_path_offset(const void *fdt, const char *path) { return fdt_path_offset_namelen(fdt, path, strlen(path)); } +int fdt_relative_path_offset(const void *fdt, const char *path, size_t offset) +{ + return fdt_relative_path_offset_namelen(fdt, path, strlen(path), + offset); +} + const char *fdt_get_name(const void *fdt, int nodeoffset, int *len) { const struct fdt_node_header *nh = fdt_offset_ptr_(fdt, nodeoffset); diff --git a/libfdt/libfdt.h b/libfdt/libfdt.h index f2675b12f674b2221273d666d51b8e31f9b4dfbe..9b61215ecd11c8990128c0b523443b83f84b1013 100644 --- a/libfdt/libfdt.h +++ b/libfdt/libfdt.h @@ -562,6 +562,59 @@ int fdt_path_offset_namelen(const void *fdt, const char *path, int namelen); */ int fdt_path_offset(const void *fdt, const char *path); +/** + * fdt_relative_path_offset - find a tree node by its relative path + * @fdt: pointer to the device tree blob + * @path: full path of the node to locate + * @offset: Offset of starting node + * + * fdt_relative_path_offset() finds a node of a given path in the device + * tree relative to a prior node. + * + * Each path component may omit the unit address portion, but the + * results of this are undefined if any such path component is + * ambiguous (that is if there are multiple nodes at the relevant + * level matching the given component, differentiated only by unit + * address). + * + * If the path is not absolute (i.e. does not begin with '/') and the + * starting offset is not 0, the first component is treated as an alias. + * That is, the property by that name is looked up in the /aliases node, + * and the value of that property used in place of that first component. + * + * For example, for this small fragment + * + * / { + * aliases { + * i2c2 = &foo; // RHS compiles to "/soc@0/i2c@30a40000/eeprom@52" + * }; + * soc@0 { + * foo: i2c@30a40000 { + * bar: eeprom@52 { + * }; + * }; + * }; + * }; + * + * these would be equivalent: + * + * /soc@0/i2c@30a40000/eeprom@52 + * i2c2/eeprom@52 + * + * returns: + * structure block offset of the node with the requested path (>=0), on + * success + * -FDT_ERR_BADPATH, given path does not begin with '/' and the first + * component is not a valid alias + * -FDT_ERR_NOTFOUND, if the requested node does not exist + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, + * -FDT_ERR_BADSTRUCTURE, + * -FDT_ERR_TRUNCATED, standard meanings. + */ +int fdt_relative_path_offset(const void *fdt, const char *path, size_t offset); + /** * fdt_get_name - retrieve the name of a given node * @fdt: pointer to the device tree blob -- 2.48.1