diff --git a/include/fdt_support.h b/include/fdt_support.h index f2e402e1822..eca9e7e3ac3 100644 --- a/include/fdt_support.h +++ b/include/fdt_support.h @@ -503,6 +503,19 @@ int fdt_kaslrseed(void *blob, bool overwrite); */ bool fdt_printable_str(const void *data, int len); +/* + * fdt_print() - Print a portion of the device tree starting from a node + * + * Recursively prints the device tree starting from the given node offset. + * The depth parameter controls how deeply nested nodes are printed. + * + * @fdt: Pointer to the device tree blob + * @nodeoffset: Node offset to start printing from + * @depth: Maximum depth to print + * Return: 0 on success, 1 on error + */ +int fdt_print(const void *fdt, int nodeoffset, int depth); + /** * fdt_print_path() - Print a portion of the device tree * diff --git a/lib/fdt_print.c b/lib/fdt_print.c index d2f3aa17de8..181291884d2 100644 --- a/lib/fdt_print.c +++ b/lib/fdt_print.c @@ -110,62 +110,30 @@ static void print_data(const void *data, int len) /****************************************************************************/ /* - * Recursively print (a portion of) the working_fdt. The depth parameter - * determines how deeply nested the fdt is printed. + * Recursively print (a portion of) an fdt starting from a node. + * The depth parameter determines how deeply nested the fdt is printed. */ -int fdt_print_path(const char *pathp, char *prop, int depth) +int fdt_print(const void *fdt, int nodeoffset, int depth) { static char tabs[MAX_LEVEL+1] = "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t" "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"; const void *nodep; /* property node pointer */ - int nodeoffset; /* node offset from libfdt */ int nextoffset; /* next node offset from libfdt */ uint32_t tag; /* tag */ int len; /* length of the property */ int level = 0; /* keep track of nesting level */ const struct fdt_property *fdt_prop; - - nodeoffset = fdt_path_offset (working_fdt, pathp); - if (nodeoffset < 0) { - /* - * Not found or something else bad happened. - */ - printf ("libfdt fdt_path_offset() returned %s\n", - fdt_strerror(nodeoffset)); - return 1; - } - /* - * The user passed in a property as well as node path. - * Print only the given property and then return. - */ - if (prop) { - nodep = fdt_getprop (working_fdt, nodeoffset, prop, &len); - if (len == 0) { - /* no property value */ - printf("%s %s\n", pathp, prop); - return 0; - } else if (nodep && len > 0) { - printf("%s = ", prop); - print_data (nodep, len); - printf("\n"); - return 0; - } else { - printf ("libfdt fdt_getprop(): %s\n", - fdt_strerror(len)); - return 1; - } - } + const char *pathp; /* - * The user passed in a node path and no property, - * print the node and all subnodes. + * Print the node and all subnodes. */ while(level >= 0) { - tag = fdt_next_tag(working_fdt, nodeoffset, &nextoffset); + tag = fdt_next_tag(fdt, nodeoffset, &nextoffset); switch(tag) { case FDT_BEGIN_NODE: - pathp = fdt_get_name(working_fdt, nodeoffset, NULL); + pathp = fdt_get_name(fdt, nodeoffset, NULL); if (level <= depth) { if (pathp == NULL) pathp = "/* NULL pointer error */"; @@ -189,9 +157,9 @@ int fdt_print_path(const char *pathp, char *prop, int depth) } break; case FDT_PROP: - fdt_prop = fdt_offset_ptr(working_fdt, nodeoffset, + fdt_prop = fdt_offset_ptr(fdt, nodeoffset, sizeof(*fdt_prop)); - pathp = fdt_string(working_fdt, + pathp = fdt_string(fdt, fdt32_to_cpu(fdt_prop->nameoff)); len = fdt32_to_cpu(fdt_prop->len); nodep = fdt_prop->data; @@ -229,3 +197,48 @@ int fdt_print_path(const char *pathp, char *prop, int depth) } return 0; } + +/* + * Print a portion of the working_fdt starting from a path. + * The depth parameter determines how deeply nested the fdt is printed. + */ +int fdt_print_path(const char *pathp, char *prop, int depth) +{ + const void *nodep; /* property node pointer */ + int nodeoffset; /* node offset from libfdt */ + int len; /* length of the property */ + + nodeoffset = fdt_path_offset (working_fdt, pathp); + if (nodeoffset < 0) { + /* + * Not found or something else bad happened. + */ + printf ("libfdt fdt_path_offset() returned %s\n", + fdt_strerror(nodeoffset)); + return 1; + } + /* + * The user passed in a property as well as node path. + * Print only the given property and then return. + */ + if (prop) { + nodep = fdt_getprop (working_fdt, nodeoffset, prop, &len); + if (len == 0) { + /* no property value */ + printf("%s %s\n", pathp, prop); + return 0; + } else if (nodep && len > 0) { + printf("%s = ", prop); + print_data (nodep, len); + printf("\n"); + return 0; + } else { + printf ("libfdt fdt_getprop(): %s\n", + fdt_strerror(len)); + return 1; + } + } + + /* Print the node and all subnodes using fdt_print() */ + return fdt_print(working_fdt, nodeoffset, depth); +}