aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/microblaze/kernel/prom.c51
-rw-r--r--arch/powerpc/kernel/prom.c69
-rw-r--r--drivers/of/fdt.c50
-rw-r--r--include/linux/of_fdt.h3
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 */
46struct device_node *of_chosen; 46struct device_node *of_chosen;
47 47
48#define early_init_dt_scan_drconf_memory(node) 0
49
50void __init early_init_dt_scan_chosen_arch(unsigned long node) 48void __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
55static int __init early_init_dt_scan_memory(unsigned long node, 53void __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, &reg);
93 size = dt_mem_next_cell(dt_root_size_cells, &reg);
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
486static int __init early_init_dt_scan_memory(unsigned long node, 486static 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 */ 497void __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, &reg);
524 size = dt_mem_next_cell(dt_root_size_cells, &reg);
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
546static void __init early_reserve_mem(void) 513static 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 */
450int __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, &reg);
483 size = dt_mem_next_cell(dt_root_size_cells, &reg);
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
446int __init early_init_dt_scan_chosen(unsigned long node, const char *uname, 496int __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);
75extern int early_init_dt_scan_chosen(unsigned long node, const char *uname, 75extern int early_init_dt_scan_chosen(unsigned long node, const char *uname,
76 int depth, void *data); 76 int depth, void *data);
77extern void early_init_dt_check_for_initrd(unsigned long node); 77extern void early_init_dt_check_for_initrd(unsigned long node);
78extern int early_init_dt_scan_memory(unsigned long node, const char *uname,
79 int depth, void *data);
80extern void early_init_dt_add_memory_arch(u64 base, u64 size);
78extern u64 dt_mem_next_cell(int s, u32 **cellp); 81extern u64 dt_mem_next_cell(int s, u32 **cellp);
79 82
80/* Early flat tree scan hooks */ 83/* Early flat tree scan hooks */