[PATCH 1/3] libfdt: Add fdt_relative_path_offset

Ayush Singh <[email protected]>
Newsgroups org.kernel.vger.devicetree-compiler
Message-ID <[email protected]>
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 <[email protected]>
---
 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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.