[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 05/11] 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 | 72 ++++++++++++++++++++++++++--------------- xen/include/xen/device_tree.h | 8 ++++ 2 files changed, 54 insertions(+), 26 deletions(-) diff --git a/xen/common/device_tree.c b/xen/common/device_tree.c index 5329956..8f5d899 100644 --- a/xen/common/device_tree.c +++ b/xen/common/device_tree.c @@ -68,7 +68,43 @@ static u32 __init prop_by_name_u32(const void *fdt, int node, return fdt32_to_cpu(*(uint32_t*)prop->data); } +#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; @@ -81,15 +117,14 @@ static void __init process_memory_node(const void *fdt, int node, if ( address_cells < 1 || size_cells < 1 ) { early_printk("fdt: node `%s': invalid #address-cells or #size-cells", - fdt_get_name(fdt, node, NULL)); + 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; } @@ -106,30 +141,15 @@ 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) @@ -157,7 +177,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 |