summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Glass <sjg@chromium.org>2013-05-07 06:11:50 +0000
committerTom Rini <trini@ti.com>2013-05-14 15:37:25 -0400
commit88f95bbadda89bfaf6a8e817bb66fd114afc1caf (patch)
tree17a3c26a6ef0df9a2469c55848a3949bebd3b3d8
parent816cb037adf94ead77593812ccd3244d506175fa (diff)
libfdt: Add fdt_next_subnode() to permit easy subnode iteration
Iterating through subnodes with libfdt is a little painful to write as we need something like this: for (depth = 0, count = 0, offset = fdt_next_node(fdt, parent_offset, &depth); (offset >= 0) && (depth > 0); offset = fdt_next_node(fdt, offset, &depth)) { if (depth == 1) { /* code body */ } } Using fdt_next_subnode() we can instead write this, which is shorter and easier to get right: for (offset = fdt_first_subnode(fdt, parent_offset); offset >= 0; offset = fdt_next_subnode(fdt, offset)) { /* code body */ } Also, it doesn't require two levels of indentation for the loop body. Signed-off-by: Simon Glass <sjg@chromium.org> (Cherry-picked from dtc commit 4e76ec79) Acked-by: Gerald Van Baren <vanbaren@cideas.com>
-rw-r--r--include/libfdt.h22
-rw-r--r--lib/libfdt/fdt.c28
2 files changed, 50 insertions, 0 deletions
diff --git a/include/libfdt.h b/include/libfdt.h
index 7403d5a6db..c5ec2acfd8 100644
--- a/include/libfdt.h
+++ b/include/libfdt.h
@@ -136,6 +136,28 @@ uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset);
int fdt_next_node(const void *fdt, int offset, int *depth);
+/**
+ * fdt_first_subnode() - get offset of first direct subnode
+ *
+ * @fdt: FDT blob
+ * @offset: Offset of node to check
+ * @return offset of first subnode, or -FDT_ERR_NOTFOUND if there is none
+ */
+int fdt_first_subnode(const void *fdt, int offset);
+
+/**
+ * fdt_next_subnode() - get offset of next direct subnode
+ *
+ * After first calling fdt_first_subnode(), call this function repeatedly to
+ * get direct subnodes of a parent node.
+ *
+ * @fdt: FDT blob
+ * @offset: Offset of previous subnode
+ * @return offset of next subnode, or -FDT_ERR_NOTFOUND if there are no more
+ * subnodes
+ */
+int fdt_next_subnode(const void *fdt, int offset);
+
/**********************************************************************/
/* General functions */
/**********************************************************************/
diff --git a/lib/libfdt/fdt.c b/lib/libfdt/fdt.c
index 387e3544b7..154e9a4461 100644
--- a/lib/libfdt/fdt.c
+++ b/lib/libfdt/fdt.c
@@ -202,6 +202,34 @@ int fdt_next_node(const void *fdt, int offset, int *depth)
return offset;
}
+int fdt_first_subnode(const void *fdt, int offset)
+{
+ int depth = 0;
+
+ offset = fdt_next_node(fdt, offset, &depth);
+ if (offset < 0 || depth != 1)
+ return -FDT_ERR_NOTFOUND;
+
+ return offset;
+}
+
+int fdt_next_subnode(const void *fdt, int offset)
+{
+ int depth = 1;
+
+ /*
+ * With respect to the parent, the depth of the next subnode will be
+ * the same as the last.
+ */
+ do {
+ offset = fdt_next_node(fdt, offset, &depth);
+ if (offset < 0 || depth < 1)
+ return -FDT_ERR_NOTFOUND;
+ } while (depth > 1);
+
+ return offset;
+}
+
const char *_fdt_find_string(const char *strtab, int tabsize, const char *s)
{
int len = strlen(s) + 1;