[PATCH 1/3] libfdt: Add fdt_relative_path_offset

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]



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





[Index of Archives]     [Device Tree]     [Device Tree Spec]     [Linux Driver Backports]     [Video for Linux]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux