diff options
Diffstat (limited to 'drivers/of')
-rw-r--r-- | drivers/of/fdt.c | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index 7f8861121a31..f84152d112b0 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/of.h> | 15 | #include <linux/of.h> |
16 | #include <linux/of_fdt.h> | 16 | #include <linux/of_fdt.h> |
17 | 17 | ||
18 | |||
18 | #ifdef CONFIG_PPC | 19 | #ifdef CONFIG_PPC |
19 | #include <asm/machdep.h> | 20 | #include <asm/machdep.h> |
20 | #endif /* CONFIG_PPC */ | 21 | #endif /* CONFIG_PPC */ |
@@ -443,6 +444,55 @@ u64 __init dt_mem_next_cell(int s, u32 **cellp) | |||
443 | return of_read_number(p, s); | 444 | return of_read_number(p, s); |
444 | } | 445 | } |
445 | 446 | ||
447 | /** | ||
448 | * early_init_dt_scan_memory - Look for an parse memory nodes | ||
449 | */ | ||
450 | int __init early_init_dt_scan_memory(unsigned long node, const char *uname, | ||
451 | int depth, void *data) | ||
452 | { | ||
453 | char *type = of_get_flat_dt_prop(node, "device_type", NULL); | ||
454 | __be32 *reg, *endp; | ||
455 | unsigned long l; | ||
456 | |||
457 | /* We are scanning "memory" nodes only */ | ||
458 | if (type == NULL) { | ||
459 | /* | ||
460 | * The longtrail doesn't have a device_type on the | ||
461 | * /memory node, so look for the node called /memory@0. | ||
462 | */ | ||
463 | if (depth != 1 || strcmp(uname, "memory@0") != 0) | ||
464 | return 0; | ||
465 | } else if (strcmp(type, "memory") != 0) | ||
466 | return 0; | ||
467 | |||
468 | reg = of_get_flat_dt_prop(node, "linux,usable-memory", &l); | ||
469 | if (reg == NULL) | ||
470 | reg = of_get_flat_dt_prop(node, "reg", &l); | ||
471 | if (reg == NULL) | ||
472 | return 0; | ||
473 | |||
474 | endp = reg + (l / sizeof(__be32)); | ||
475 | |||
476 | pr_debug("memory scan node %s, reg size %ld, data: %x %x %x %x,\n", | ||
477 | uname, l, reg[0], reg[1], reg[2], reg[3]); | ||
478 | |||
479 | while ((endp - reg) >= (dt_root_addr_cells + dt_root_size_cells)) { | ||
480 | u64 base, size; | ||
481 | |||
482 | base = dt_mem_next_cell(dt_root_addr_cells, ®); | ||
483 | size = dt_mem_next_cell(dt_root_size_cells, ®); | ||
484 | |||
485 | if (size == 0) | ||
486 | continue; | ||
487 | pr_debug(" - %llx , %llx\n", (unsigned long long)base, | ||
488 | (unsigned long long)size); | ||
489 | |||
490 | early_init_dt_add_memory_arch(base, size); | ||
491 | } | ||
492 | |||
493 | return 0; | ||
494 | } | ||
495 | |||
446 | int __init early_init_dt_scan_chosen(unsigned long node, const char *uname, | 496 | int __init early_init_dt_scan_chosen(unsigned long node, const char *uname, |
447 | int depth, void *data) | 497 | int depth, void *data) |
448 | { | 498 | { |