diff options
| author | Grant Likely <grant.likely@secretlab.ca> | 2010-02-01 23:34:14 -0500 |
|---|---|---|
| committer | Grant Likely <grant.likely@secretlab.ca> | 2010-02-09 10:33:10 -0500 |
| commit | 51975db0b7333cf389b64b5040c2a910341d241a (patch) | |
| tree | aba9d6bf56eec915265a8b630c3192affc2a549c | |
| parent | 71a157e8edca55198e808f8561dd49017a54ee34 (diff) | |
of/flattree: merge early_init_dt_scan_memory() common code
Merge common code between PowerPC and Microblaze architectures.
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Acked-by: Michal Simek <monstr@monstr.eu>
| -rw-r--r-- | arch/microblaze/kernel/prom.c | 51 | ||||
| -rw-r--r-- | arch/powerpc/kernel/prom.c | 69 | ||||
| -rw-r--r-- | drivers/of/fdt.c | 50 | ||||
| -rw-r--r-- | include/linux/of_fdt.h | 3 |
4 files changed, 73 insertions, 100 deletions
diff --git a/arch/microblaze/kernel/prom.c b/arch/microblaze/kernel/prom.c index f7bd0ee8d481..459c32e4a5fe 100644 --- a/arch/microblaze/kernel/prom.c +++ b/arch/microblaze/kernel/prom.c | |||
| @@ -45,61 +45,14 @@ | |||
| 45 | /* export that to outside world */ | 45 | /* export that to outside world */ |
| 46 | struct device_node *of_chosen; | 46 | struct device_node *of_chosen; |
| 47 | 47 | ||
| 48 | #define early_init_dt_scan_drconf_memory(node) 0 | ||
| 49 | |||
| 50 | void __init early_init_dt_scan_chosen_arch(unsigned long node) | 48 | void __init early_init_dt_scan_chosen_arch(unsigned long node) |
| 51 | { | 49 | { |
| 52 | /* No Microblaze specific code here */ | 50 | /* No Microblaze specific code here */ |
| 53 | } | 51 | } |
| 54 | 52 | ||
| 55 | static int __init early_init_dt_scan_memory(unsigned long node, | 53 | void __init early_init_dt_add_memory_arch(u64 base, u64 size) |
| 56 | const char *uname, int depth, void *data) | ||
| 57 | { | 54 | { |
| 58 | char *type = of_get_flat_dt_prop(node, "device_type", NULL); | 55 | lmb_add(base, size); |
| 59 | __be32 *reg, *endp; | ||
| 60 | unsigned long l; | ||
| 61 | |||
| 62 | /* Look for the ibm,dynamic-reconfiguration-memory node */ | ||
| 63 | /* if (depth == 1 && | ||
| 64 | strcmp(uname, "ibm,dynamic-reconfiguration-memory") == 0) | ||
| 65 | return early_init_dt_scan_drconf_memory(node); | ||
| 66 | */ | ||
| 67 | /* We are scanning "memory" nodes only */ | ||
| 68 | if (type == NULL) { | ||
| 69 | /* | ||
| 70 | * The longtrail doesn't have a device_type on the | ||
| 71 | * /memory node, so look for the node called /memory@0. | ||
| 72 | */ | ||
| 73 | if (depth != 1 || strcmp(uname, "memory@0") != 0) | ||
| 74 | return 0; | ||
| 75 | } else if (strcmp(type, "memory") != 0) | ||
| 76 | return 0; | ||
| 77 | |||
| 78 | reg = (__be32 *)of_get_flat_dt_prop(node, "linux,usable-memory", &l); | ||
| 79 | if (reg == NULL) | ||
| 80 | reg = (__be32 *)of_get_flat_dt_prop(node, "reg", &l); | ||
| 81 | if (reg == NULL) | ||
| 82 | return 0; | ||
| 83 | |||
| 84 | endp = reg + (l / sizeof(__be32)); | ||
| 85 | |||
| 86 | pr_debug("memory scan node %s, reg size %ld, data: %x %x %x %x,\n", | ||
| 87 | uname, l, reg[0], reg[1], reg[2], reg[3]); | ||
| 88 | |||
| 89 | while ((endp - reg) >= (dt_root_addr_cells + dt_root_size_cells)) { | ||
| 90 | u64 base, size; | ||
| 91 | |||
| 92 | base = dt_mem_next_cell(dt_root_addr_cells, ®); | ||
| 93 | size = dt_mem_next_cell(dt_root_size_cells, ®); | ||
| 94 | |||
| 95 | if (size == 0) | ||
| 96 | continue; | ||
| 97 | pr_debug(" - %llx , %llx\n", (unsigned long long)base, | ||
| 98 | (unsigned long long)size); | ||
| 99 | |||
| 100 | lmb_add(base, size); | ||
| 101 | } | ||
| 102 | return 0; | ||
| 103 | } | 56 | } |
| 104 | 57 | ||
| 105 | #ifdef CONFIG_EARLY_PRINTK | 58 | #ifdef CONFIG_EARLY_PRINTK |
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index 28be19ab0f18..e0f368ff8d12 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c | |||
| @@ -483,64 +483,31 @@ static int __init early_init_dt_scan_drconf_memory(unsigned long node) | |||
| 483 | #define early_init_dt_scan_drconf_memory(node) 0 | 483 | #define early_init_dt_scan_drconf_memory(node) 0 |
| 484 | #endif /* CONFIG_PPC_PSERIES */ | 484 | #endif /* CONFIG_PPC_PSERIES */ |
| 485 | 485 | ||
| 486 | static int __init early_init_dt_scan_memory(unsigned long node, | 486 | static int __init early_init_dt_scan_memory_ppc(unsigned long node, |
| 487 | const char *uname, int depth, void *data) | 487 | const char *uname, |
| 488 | int depth, void *data) | ||
| 488 | { | 489 | { |
| 489 | char *type = of_get_flat_dt_prop(node, "device_type", NULL); | ||
| 490 | __be32 *reg, *endp; | ||
| 491 | unsigned long l; | ||
| 492 | |||
| 493 | /* Look for the ibm,dynamic-reconfiguration-memory node */ | ||
| 494 | if (depth == 1 && | 490 | if (depth == 1 && |
| 495 | strcmp(uname, "ibm,dynamic-reconfiguration-memory") == 0) | 491 | strcmp(uname, "ibm,dynamic-reconfiguration-memory") == 0) |
| 496 | return early_init_dt_scan_drconf_memory(node); | 492 | return early_init_dt_scan_drconf_memory(node); |
| 493 | |||
| 494 | return early_init_dt_scan_memory(node, uname, depth, data); | ||
| 495 | } | ||
| 497 | 496 | ||
| 498 | /* We are scanning "memory" nodes only */ | 497 | void __init early_init_dt_add_memory_arch(u64 base, u64 size) |
| 499 | if (type == NULL) { | 498 | { |
| 500 | /* | 499 | #if defined(CONFIG_PPC64) |
| 501 | * The longtrail doesn't have a device_type on the | 500 | if (iommu_is_off) { |
| 502 | * /memory node, so look for the node called /memory@0. | 501 | if (base >= 0x80000000ul) |
| 503 | */ | 502 | return; |
| 504 | if (depth != 1 || strcmp(uname, "memory@0") != 0) | 503 | if ((base + size) > 0x80000000ul) |
| 505 | return 0; | 504 | size = 0x80000000ul - base; |
| 506 | } else if (strcmp(type, "memory") != 0) | 505 | } |
| 507 | return 0; | ||
| 508 | |||
| 509 | reg = of_get_flat_dt_prop(node, "linux,usable-memory", &l); | ||
| 510 | if (reg == NULL) | ||
| 511 | reg = of_get_flat_dt_prop(node, "reg", &l); | ||
| 512 | if (reg == NULL) | ||
| 513 | return 0; | ||
| 514 | |||
| 515 | endp = reg + (l / sizeof(__be32)); | ||
| 516 | |||
| 517 | DBG("memory scan node %s, reg size %ld, data: %x %x %x %x,\n", | ||
| 518 | uname, l, reg[0], reg[1], reg[2], reg[3]); | ||
| 519 | |||
| 520 | while ((endp - reg) >= (dt_root_addr_cells + dt_root_size_cells)) { | ||
| 521 | u64 base, size; | ||
| 522 | |||
| 523 | base = dt_mem_next_cell(dt_root_addr_cells, ®); | ||
| 524 | size = dt_mem_next_cell(dt_root_size_cells, ®); | ||
| 525 | |||
| 526 | if (size == 0) | ||
| 527 | continue; | ||
| 528 | DBG(" - %llx , %llx\n", (unsigned long long)base, | ||
| 529 | (unsigned long long)size); | ||
| 530 | #ifdef CONFIG_PPC64 | ||
| 531 | if (iommu_is_off) { | ||
| 532 | if (base >= 0x80000000ul) | ||
| 533 | continue; | ||
| 534 | if ((base + size) > 0x80000000ul) | ||
| 535 | size = 0x80000000ul - base; | ||
| 536 | } | ||
| 537 | #endif | 506 | #endif |
| 538 | lmb_add(base, size); | ||
| 539 | 507 | ||
| 540 | memstart_addr = min((u64)memstart_addr, base); | 508 | lmb_add(base, size); |
| 541 | } | ||
| 542 | 509 | ||
| 543 | return 0; | 510 | memstart_addr = min((u64)memstart_addr, base); |
| 544 | } | 511 | } |
| 545 | 512 | ||
| 546 | static void __init early_reserve_mem(void) | 513 | static void __init early_reserve_mem(void) |
| @@ -706,7 +673,7 @@ void __init early_init_devtree(void *params) | |||
| 706 | /* Scan memory nodes and rebuild LMBs */ | 673 | /* Scan memory nodes and rebuild LMBs */ |
| 707 | lmb_init(); | 674 | lmb_init(); |
| 708 | of_scan_flat_dt(early_init_dt_scan_root, NULL); | 675 | of_scan_flat_dt(early_init_dt_scan_root, NULL); |
| 709 | of_scan_flat_dt(early_init_dt_scan_memory, NULL); | 676 | of_scan_flat_dt(early_init_dt_scan_memory_ppc, NULL); |
| 710 | 677 | ||
| 711 | /* Save command line for /proc/cmdline and then parse parameters */ | 678 | /* Save command line for /proc/cmdline and then parse parameters */ |
| 712 | strlcpy(boot_command_line, cmd_line, COMMAND_LINE_SIZE); | 679 | strlcpy(boot_command_line, cmd_line, COMMAND_LINE_SIZE); |
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 | { |
diff --git a/include/linux/of_fdt.h b/include/linux/of_fdt.h index fbf29610616d..bf26bd5df9f1 100644 --- a/include/linux/of_fdt.h +++ b/include/linux/of_fdt.h | |||
| @@ -75,6 +75,9 @@ extern void early_init_dt_scan_chosen_arch(unsigned long node); | |||
| 75 | extern int early_init_dt_scan_chosen(unsigned long node, const char *uname, | 75 | extern int early_init_dt_scan_chosen(unsigned long node, const char *uname, |
| 76 | int depth, void *data); | 76 | int depth, void *data); |
| 77 | extern void early_init_dt_check_for_initrd(unsigned long node); | 77 | extern void early_init_dt_check_for_initrd(unsigned long node); |
| 78 | extern int early_init_dt_scan_memory(unsigned long node, const char *uname, | ||
| 79 | int depth, void *data); | ||
| 80 | extern void early_init_dt_add_memory_arch(u64 base, u64 size); | ||
| 78 | extern u64 dt_mem_next_cell(int s, u32 **cellp); | 81 | extern u64 dt_mem_next_cell(int s, u32 **cellp); |
| 79 | 82 | ||
| 80 | /* Early flat tree scan hooks */ | 83 | /* Early flat tree scan hooks */ |
