[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] device tree: add device_tree_for_each_node()
# HG changeset patch # User David Vrabel <david.vrabel@xxxxxxxxxx> # Date 1332426405 0 # Node ID cb2e700ce5bb459ecc98c62e4f73ad9d35f4101a # Parent da5b84cf21c27edf28b68cc251d7664c1874f791 device tree: add device_tree_for_each_node() 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> Committed-by: Ian Campbell <ian.campbell@xxxxxxxxxx> --- diff -r da5b84cf21c2 -r cb2e700ce5bb xen/common/device_tree.c --- a/xen/common/device_tree.c Thu Mar 22 14:26:44 2012 +0000 +++ b/xen/common/device_tree.c Thu Mar 22 14:26:45 2012 +0000 @@ -68,7 +68,43 @@ 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 @@ 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 @@ } } -#define MAX_DEPTH 16 +static int __init early_scan_node(const void *fdt, + int node, const char *name, int depth, + u32 address_cells, u32 size_cells, + void *data) +{ + if ( node_matches(fdt, node, "memory") ) + process_memory_node(fdt, node, name, address_cells, size_cells); -static void __init early_scan(const void *fdt) -{ - 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; - } - - 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 @@ 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 -r da5b84cf21c2 -r cb2e700ce5bb xen/include/xen/device_tree.h --- a/xen/include/xen/device_tree.h Thu Mar 22 14:26:44 2012 +0000 +++ b/xen/include/xen/device_tree.h Thu Mar 22 14:26:45 2012 +0000 @@ -28,10 +28,18 @@ 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 _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |