diff options
| author | Grant Likely <grant.likely@secretlab.ca> | 2009-11-23 22:07:01 -0500 |
|---|---|---|
| committer | Grant Likely <grant.likely@secretlab.ca> | 2009-11-23 22:07:01 -0500 |
| commit | 41f880091c15b039ffcc8b3d831656b81517a6d3 (patch) | |
| tree | a9919151491356b6445ecd9c613a60f69d207927 | |
| parent | bbd33931a08362f78266a4016211a35947b91041 (diff) | |
of/flattree: Merge unflatten_device_tree
Merge common code between PowerPC and MicroBlaze
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Reviewed-by: Wolfram Sang <w.sang@pengutronix.de>
Tested-by: Michal Simek <monstr@monstr.eu>
| -rw-r--r-- | arch/microblaze/include/asm/prom.h | 1 | ||||
| -rw-r--r-- | arch/microblaze/kernel/prom.c | 49 | ||||
| -rw-r--r-- | arch/powerpc/kernel/prom.c | 50 | ||||
| -rw-r--r-- | drivers/of/fdt.c | 52 | ||||
| -rw-r--r-- | include/linux/of.h | 3 | ||||
| -rw-r--r-- | include/linux/of_fdt.h | 4 |
6 files changed, 55 insertions, 104 deletions
diff --git a/arch/microblaze/include/asm/prom.h b/arch/microblaze/include/asm/prom.h index ef3ec1d6ceb3..07d1063f9aae 100644 --- a/arch/microblaze/include/asm/prom.h +++ b/arch/microblaze/include/asm/prom.h | |||
| @@ -37,7 +37,6 @@ extern struct device_node *of_chosen; | |||
| 37 | 37 | ||
| 38 | #define HAVE_ARCH_DEVTREE_FIXUPS | 38 | #define HAVE_ARCH_DEVTREE_FIXUPS |
| 39 | 39 | ||
| 40 | extern struct device_node *allnodes; /* temporary while merging */ | ||
| 41 | extern rwlock_t devtree_lock; /* temporary while merging */ | 40 | extern rwlock_t devtree_lock; /* temporary while merging */ |
| 42 | 41 | ||
| 43 | /* For updating the device tree at runtime */ | 42 | /* For updating the device tree at runtime */ |
diff --git a/arch/microblaze/kernel/prom.c b/arch/microblaze/kernel/prom.c index 021770abfbd7..901d538c15ef 100644 --- a/arch/microblaze/kernel/prom.c +++ b/arch/microblaze/kernel/prom.c | |||
| @@ -50,55 +50,6 @@ typedef u32 cell_t; | |||
| 50 | /* export that to outside world */ | 50 | /* export that to outside world */ |
| 51 | struct device_node *of_chosen; | 51 | struct device_node *of_chosen; |
| 52 | 52 | ||
| 53 | /** | ||
| 54 | * unflattens the device-tree passed by the firmware, creating the | ||
| 55 | * tree of struct device_node. It also fills the "name" and "type" | ||
| 56 | * pointers of the nodes so the normal device-tree walking functions | ||
| 57 | * can be used (this used to be done by finish_device_tree) | ||
| 58 | */ | ||
| 59 | void __init unflatten_device_tree(void) | ||
| 60 | { | ||
| 61 | unsigned long start, mem, size; | ||
| 62 | struct device_node **allnextp = &allnodes; | ||
| 63 | |||
| 64 | pr_debug(" -> unflatten_device_tree()\n"); | ||
| 65 | |||
| 66 | /* First pass, scan for size */ | ||
| 67 | start = ((unsigned long)initial_boot_params) + | ||
| 68 | initial_boot_params->off_dt_struct; | ||
| 69 | size = unflatten_dt_node(0, &start, NULL, NULL, 0); | ||
| 70 | size = (size | 3) + 1; | ||
| 71 | |||
| 72 | pr_debug(" size is %lx, allocating...\n", size); | ||
| 73 | |||
| 74 | /* Allocate memory for the expanded device tree */ | ||
| 75 | mem = lmb_alloc(size + 4, __alignof__(struct device_node)); | ||
| 76 | mem = (unsigned long) __va(mem); | ||
| 77 | |||
| 78 | ((u32 *)mem)[size / 4] = 0xdeadbeef; | ||
| 79 | |||
| 80 | pr_debug(" unflattening %lx...\n", mem); | ||
| 81 | |||
| 82 | /* Second pass, do actual unflattening */ | ||
| 83 | start = ((unsigned long)initial_boot_params) + | ||
| 84 | initial_boot_params->off_dt_struct; | ||
| 85 | unflatten_dt_node(mem, &start, NULL, &allnextp, 0); | ||
| 86 | if (*((u32 *)start) != OF_DT_END) | ||
| 87 | printk(KERN_WARNING "Weird tag at end of tree: %08x\n", | ||
| 88 | *((u32 *)start)); | ||
| 89 | if (((u32 *)mem)[size / 4] != 0xdeadbeef) | ||
| 90 | printk(KERN_WARNING "End of tree marker overwritten: %08x\n", | ||
| 91 | ((u32 *)mem)[size / 4]); | ||
| 92 | *allnextp = NULL; | ||
| 93 | |||
| 94 | /* Get pointer to OF "/chosen" node for use everywhere */ | ||
| 95 | of_chosen = of_find_node_by_path("/chosen"); | ||
| 96 | if (of_chosen == NULL) | ||
| 97 | of_chosen = of_find_node_by_path("/chosen@0"); | ||
| 98 | |||
| 99 | pr_debug(" <- unflatten_device_tree()\n"); | ||
| 100 | } | ||
| 101 | |||
| 102 | #define early_init_dt_scan_drconf_memory(node) 0 | 53 | #define early_init_dt_scan_drconf_memory(node) 0 |
| 103 | 54 | ||
| 104 | static int __init early_init_dt_scan_cpus(unsigned long node, | 55 | static int __init early_init_dt_scan_cpus(unsigned long node, |
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index a102a0a33ed1..1280f3484ad3 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c | |||
| @@ -73,8 +73,6 @@ unsigned long tce_alloc_start, tce_alloc_end; | |||
| 73 | 73 | ||
| 74 | typedef u32 cell_t; | 74 | typedef u32 cell_t; |
| 75 | 75 | ||
| 76 | extern struct device_node *allnodes; /* temporary while merging */ | ||
| 77 | |||
| 78 | extern rwlock_t devtree_lock; /* temporary while merging */ | 76 | extern rwlock_t devtree_lock; /* temporary while merging */ |
| 79 | 77 | ||
| 80 | /* export that to outside world */ | 78 | /* export that to outside world */ |
| @@ -119,54 +117,6 @@ static void __init move_device_tree(void) | |||
| 119 | DBG("<- move_device_tree\n"); | 117 | DBG("<- move_device_tree\n"); |
| 120 | } | 118 | } |
| 121 | 119 | ||
| 122 | /** | ||
| 123 | * unflattens the device-tree passed by the firmware, creating the | ||
| 124 | * tree of struct device_node. It also fills the "name" and "type" | ||
| 125 | * pointers of the nodes so the normal device-tree walking functions | ||
| 126 | * can be used (this used to be done by finish_device_tree) | ||
| 127 | */ | ||
| 128 | void __init unflatten_device_tree(void) | ||
| 129 | { | ||
| 130 | unsigned long start, mem, size; | ||
| 131 | struct device_node **allnextp = &allnodes; | ||
| 132 | |||
| 133 | DBG(" -> unflatten_device_tree()\n"); | ||
| 134 | |||
| 135 | /* First pass, scan for size */ | ||
| 136 | start = ((unsigned long)initial_boot_params) + | ||
| 137 | initial_boot_params->off_dt_struct; | ||
| 138 | size = unflatten_dt_node(0, &start, NULL, NULL, 0); | ||
| 139 | size = (size | 3) + 1; | ||
| 140 | |||
| 141 | DBG(" size is %lx, allocating...\n", size); | ||
| 142 | |||
| 143 | /* Allocate memory for the expanded device tree */ | ||
| 144 | mem = lmb_alloc(size + 4, __alignof__(struct device_node)); | ||
| 145 | mem = (unsigned long) __va(mem); | ||
| 146 | |||
| 147 | ((u32 *)mem)[size / 4] = 0xdeadbeef; | ||
| 148 | |||
| 149 | DBG(" unflattening %lx...\n", mem); | ||
| 150 | |||
| 151 | /* Second pass, do actual unflattening */ | ||
| 152 | start = ((unsigned long)initial_boot_params) + | ||
| 153 | initial_boot_params->off_dt_struct; | ||
| 154 | unflatten_dt_node(mem, &start, NULL, &allnextp, 0); | ||
| 155 | if (*((u32 *)start) != OF_DT_END) | ||
| 156 | printk(KERN_WARNING "Weird tag at end of tree: %08x\n", *((u32 *)start)); | ||
| 157 | if (((u32 *)mem)[size / 4] != 0xdeadbeef) | ||
| 158 | printk(KERN_WARNING "End of tree marker overwritten: %08x\n", | ||
| 159 | ((u32 *)mem)[size / 4] ); | ||
| 160 | *allnextp = NULL; | ||
| 161 | |||
| 162 | /* Get pointer to OF "/chosen" node for use everywhere */ | ||
| 163 | of_chosen = of_find_node_by_path("/chosen"); | ||
| 164 | if (of_chosen == NULL) | ||
| 165 | of_chosen = of_find_node_by_path("/chosen@0"); | ||
| 166 | |||
| 167 | DBG(" <- unflatten_device_tree()\n"); | ||
| 168 | } | ||
| 169 | |||
| 170 | /* | 120 | /* |
| 171 | * ibm,pa-features is a per-cpu property that contains a string of | 121 | * ibm,pa-features is a per-cpu property that contains a string of |
| 172 | * attribute descriptors, each of which has a 2 byte header plus up | 122 | * attribute descriptors, each of which has a 2 byte header plus up |
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index 6852ecf6d1e1..43d236cbc17b 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c | |||
| @@ -9,6 +9,8 @@ | |||
| 9 | * version 2 as published by the Free Software Foundation. | 9 | * version 2 as published by the Free Software Foundation. |
| 10 | */ | 10 | */ |
| 11 | 11 | ||
| 12 | #include <linux/kernel.h> | ||
| 13 | #include <linux/lmb.h> | ||
| 12 | #include <linux/of.h> | 14 | #include <linux/of.h> |
| 13 | #include <linux/of_fdt.h> | 15 | #include <linux/of_fdt.h> |
| 14 | 16 | ||
| @@ -366,3 +368,53 @@ unsigned long __init unflatten_dt_node(unsigned long mem, | |||
| 366 | *p += 4; | 368 | *p += 4; |
| 367 | return mem; | 369 | return mem; |
| 368 | } | 370 | } |
| 371 | |||
| 372 | /** | ||
| 373 | * unflatten_device_tree - create tree of device_nodes from flat blob | ||
| 374 | * | ||
| 375 | * unflattens the device-tree passed by the firmware, creating the | ||
| 376 | * tree of struct device_node. It also fills the "name" and "type" | ||
| 377 | * pointers of the nodes so the normal device-tree walking functions | ||
| 378 | * can be used. | ||
| 379 | */ | ||
| 380 | void __init unflatten_device_tree(void) | ||
| 381 | { | ||
| 382 | unsigned long start, mem, size; | ||
| 383 | struct device_node **allnextp = &allnodes; | ||
| 384 | |||
| 385 | pr_debug(" -> unflatten_device_tree()\n"); | ||
| 386 | |||
| 387 | /* First pass, scan for size */ | ||
| 388 | start = ((unsigned long)initial_boot_params) + | ||
| 389 | initial_boot_params->off_dt_struct; | ||
| 390 | size = unflatten_dt_node(0, &start, NULL, NULL, 0); | ||
| 391 | size = (size | 3) + 1; | ||
| 392 | |||
| 393 | pr_debug(" size is %lx, allocating...\n", size); | ||
| 394 | |||
| 395 | /* Allocate memory for the expanded device tree */ | ||
| 396 | mem = lmb_alloc(size + 4, __alignof__(struct device_node)); | ||
| 397 | mem = (unsigned long) __va(mem); | ||
| 398 | |||
| 399 | ((u32 *)mem)[size / 4] = 0xdeadbeef; | ||
| 400 | |||
| 401 | pr_debug(" unflattening %lx...\n", mem); | ||
| 402 | |||
| 403 | /* Second pass, do actual unflattening */ | ||
| 404 | start = ((unsigned long)initial_boot_params) + | ||
| 405 | initial_boot_params->off_dt_struct; | ||
| 406 | unflatten_dt_node(mem, &start, NULL, &allnextp, 0); | ||
| 407 | if (*((u32 *)start) != OF_DT_END) | ||
| 408 | pr_warning("Weird tag at end of tree: %08x\n", *((u32 *)start)); | ||
| 409 | if (((u32 *)mem)[size / 4] != 0xdeadbeef) | ||
| 410 | pr_warning("End of tree marker overwritten: %08x\n", | ||
| 411 | ((u32 *)mem)[size / 4]); | ||
| 412 | *allnextp = NULL; | ||
| 413 | |||
| 414 | /* Get pointer to OF "/chosen" node for use everywhere */ | ||
| 415 | of_chosen = of_find_node_by_path("/chosen"); | ||
| 416 | if (of_chosen == NULL) | ||
| 417 | of_chosen = of_find_node_by_path("/chosen@0"); | ||
| 418 | |||
| 419 | pr_debug(" <- unflatten_device_tree()\n"); | ||
| 420 | } | ||
diff --git a/include/linux/of.h b/include/linux/of.h index e7facd8fbce8..bec215792c4f 100644 --- a/include/linux/of.h +++ b/include/linux/of.h | |||
| @@ -63,6 +63,9 @@ struct device_node { | |||
| 63 | #endif | 63 | #endif |
| 64 | }; | 64 | }; |
| 65 | 65 | ||
| 66 | /* Pointer for first entry in chain of all nodes. */ | ||
| 67 | extern struct device_node *allnodes; | ||
| 68 | |||
| 66 | static inline int of_node_check_flag(struct device_node *n, unsigned long flag) | 69 | static inline int of_node_check_flag(struct device_node *n, unsigned long flag) |
| 67 | { | 70 | { |
| 68 | return test_bit(flag, &n->_flags); | 71 | return test_bit(flag, &n->_flags); |
diff --git a/include/linux/of_fdt.h b/include/linux/of_fdt.h index ace9068e07e8..81231e04e8f3 100644 --- a/include/linux/of_fdt.h +++ b/include/linux/of_fdt.h | |||
| @@ -69,10 +69,6 @@ extern void *of_get_flat_dt_prop(unsigned long node, const char *name, | |||
| 69 | unsigned long *size); | 69 | unsigned long *size); |
| 70 | extern int of_flat_dt_is_compatible(unsigned long node, const char *name); | 70 | extern int of_flat_dt_is_compatible(unsigned long node, const char *name); |
| 71 | extern unsigned long of_get_flat_dt_root(void); | 71 | extern unsigned long of_get_flat_dt_root(void); |
| 72 | extern unsigned long unflatten_dt_node(unsigned long mem, unsigned long *p, | ||
| 73 | struct device_node *dad, | ||
| 74 | struct device_node ***allnextpp, | ||
| 75 | unsigned long fpsize); | ||
| 76 | 72 | ||
| 77 | /* Other Prototypes */ | 73 | /* Other Prototypes */ |
| 78 | extern void finish_device_tree(void); | 74 | extern void finish_device_tree(void); |
