[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 3/8] device tree: add device_tree_for_each_node()
From: David Vrabel <david.vrabel@xxxxxxxxxx> Add device_tree_for_each_node() to iterate over all nodes in a flat device tree. Use this in device_tree_early_init(). Signed-off-by: David Vrabel <david.vrabel@xxxxxxxxxx> --- xen/common/device_tree.c | 71 ++++++++++++++++++++++++++--------------- xen/include/xen/device_tree.h | 8 +++++ 2 files changed, 53 insertions(+), 26 deletions(-) diff --git a/xen/common/device_tree.c b/xen/common/device_tree.c index e5df748..e95ff3c 100644 --- a/xen/common/device_tree.c +++ b/xen/common/device_tree.c @@ -66,7 +66,42 @@ static u32 __init prop_by_name_u32(const void *fdt, int node, const char *prop_n return fdt32_to_cpu(*(uint32_t*)prop->data); } -static void __init process_memory_node(const void *fdt, int node, +#define MAX_DEPTH 16 + +/** + * device_tree_for_each_node - iterate over all device tree nodes + * @fdt: flat device tree. + * @func: function to call for each node. + * @data: data to pass to @func. + */ +int device_tree_for_each_node(const void *fdt, + device_tree_node_func func, void *data) +{ + int node; + int depth; + u32 address_cells[MAX_DEPTH]; + u32 size_cells[MAX_DEPTH]; + int ret; + + for (node = 0, depth = 0; + node >=0 && depth >= 0; + node = fdt_next_node(fdt, node, &depth)) + { + if (depth >= MAX_DEPTH) + continue; + + address_cells[depth] = prop_by_name_u32(fdt, node, "#address-cells"); + size_cells[depth] = prop_by_name_u32(fdt, node, "#size-cells"); + + ret = func(fdt, node, fdt_get_name(fdt, node, NULL), depth, + address_cells[depth-1], size_cells[depth-1], data); + if (ret < 0) + return ret; + } + return 0; +} + +static void __init process_memory_node(const void *fdt, int node, const char *name, u32 address_cells, u32 size_cells) { const struct fdt_property *prop; @@ -77,15 +112,13 @@ static void __init process_memory_node(const void *fdt, int node, paddr_t start, size; if (address_cells < 1 || size_cells < 1) { - early_printk("fdt: node `%s': invalid #address-cells or #size-cells", - fdt_get_name(fdt, node, NULL)); + early_printk("fdt: node `%s': invalid #address-cells or #size-cells", name); return; } prop = fdt_get_property(fdt, node, "reg", NULL); if (!prop) { - early_printk("fdt: node `%s': missing `reg' property\n", - fdt_get_name(fdt, node, NULL)); + early_printk("fdt: node `%s': missing `reg' property\n", name); return; } @@ -101,28 +134,14 @@ static void __init process_memory_node(const void *fdt, int node, } } -#define MAX_DEPTH 16 - -static void __init early_scan(const void *fdt) +static int __init early_scan_node(const void *fdt, + int node, const char *name, int depth, + u32 address_cells, u32 size_cells, void *data) { - int node; - int depth; - u32 address_cells[MAX_DEPTH]; - u32 size_cells[MAX_DEPTH]; - - for (node = 0; depth >= 0; node = fdt_next_node(fdt, node, &depth)) { - if (depth >= MAX_DEPTH) { - early_printk("fdt: node '%s': nested too deep\n", - fdt_get_name(fdt, node, NULL)); - continue; - } + if (node_matches(fdt, node, "memory")) + process_memory_node(fdt, node, name, address_cells, size_cells); - address_cells[depth] = prop_by_name_u32(fdt, node, "#address-cells"); - size_cells[depth] = prop_by_name_u32(fdt, node, "#size-cells"); - - if (node_matches(fdt, node, "memory")) - process_memory_node(fdt, node, address_cells[depth-1], size_cells[depth-1]); - } + return 0; } static void __init early_print_info(void) @@ -149,7 +168,7 @@ size_t __init device_tree_early_init(const void *fdt) if (ret < 0) early_panic("No valid device tree\n"); - early_scan(fdt); + device_tree_for_each_node((void *)fdt, early_scan_node, NULL); early_print_info(); return fdt_totalsize(fdt); diff --git a/xen/include/xen/device_tree.h b/xen/include/xen/device_tree.h index 28a3dee..505f3e3 100644 --- a/xen/include/xen/device_tree.h +++ b/xen/include/xen/device_tree.h @@ -28,10 +28,18 @@ struct dt_early_info { struct dt_mem_info mem; }; +typedef int (*device_tree_node_func)(const void *fdt, + int node, const char *name, int depth, + u32 address_cells, u32 size_cells, + void *data); + extern struct dt_early_info early_info; extern void *device_tree_flattened; size_t device_tree_early_init(const void *fdt); paddr_t device_tree_get_xen_paddr(void); +int device_tree_for_each_node(const void *fdt, + device_tree_node_func func, void *data); + #endif -- 1.7.2.5 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |