diff options
author | Jeremy Kerr <jk@ozlabs.org> | 2013-04-24 02:26:30 -0400 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2013-06-20 02:55:11 -0400 |
commit | 0962e8004e97409072bb6caee7b3ba948a5fb93a (patch) | |
tree | 9fdf0269b2cb7a2ce2c1c36da33d1663ba4dce8f /arch | |
parent | d5d8ec895ca599fbde43efe3a2f9714315e3d298 (diff) |
powerpc/prom: Scan reserved-ranges node for memory reservations
Based on benh's proposal at
https://lists.ozlabs.org/pipermail/linuxppc-dev/2012-September/101237.html,
this change provides support for reserving memory from the
reserved-ranges node at the root of the device tree.
We just call memblock_reserve on these ranges for now.
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/powerpc/kernel/prom.c | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index 8b6f7a99cce2..9c753bc9885d 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c | |||
@@ -559,6 +559,33 @@ void __init early_init_dt_setup_initrd_arch(unsigned long start, | |||
559 | } | 559 | } |
560 | #endif | 560 | #endif |
561 | 561 | ||
562 | static bool __init early_reserve_mem_dt(void) | ||
563 | { | ||
564 | unsigned long i, len, dt_root; | ||
565 | const __be32 *prop; | ||
566 | |||
567 | dt_root = of_get_flat_dt_root(); | ||
568 | |||
569 | prop = of_get_flat_dt_prop(dt_root, "reserved-ranges", &len); | ||
570 | |||
571 | if (!prop) | ||
572 | return false; | ||
573 | |||
574 | /* Each reserved range is an (address,size) pair, 2 cells each, | ||
575 | * totalling 4 cells per range. */ | ||
576 | for (i = 0; i < len / (sizeof(*prop) * 4); i++) { | ||
577 | u64 base, size; | ||
578 | |||
579 | base = of_read_number(prop + (i * 4) + 0, 2); | ||
580 | size = of_read_number(prop + (i * 4) + 2, 2); | ||
581 | |||
582 | if (size) | ||
583 | memblock_reserve(base, size); | ||
584 | } | ||
585 | |||
586 | return true; | ||
587 | } | ||
588 | |||
562 | static void __init early_reserve_mem(void) | 589 | static void __init early_reserve_mem(void) |
563 | { | 590 | { |
564 | u64 base, size; | 591 | u64 base, size; |
@@ -574,6 +601,14 @@ static void __init early_reserve_mem(void) | |||
574 | self_size = initial_boot_params->totalsize; | 601 | self_size = initial_boot_params->totalsize; |
575 | memblock_reserve(self_base, self_size); | 602 | memblock_reserve(self_base, self_size); |
576 | 603 | ||
604 | /* | ||
605 | * Try looking for reserved-regions property in the DT first; if | ||
606 | * it's present, it'll contain all of the necessary reservation | ||
607 | * info | ||
608 | */ | ||
609 | if (early_reserve_mem_dt()) | ||
610 | return; | ||
611 | |||
577 | #ifdef CONFIG_BLK_DEV_INITRD | 612 | #ifdef CONFIG_BLK_DEV_INITRD |
578 | /* then reserve the initrd, if any */ | 613 | /* then reserve the initrd, if any */ |
579 | if (initrd_start && (initrd_end > initrd_start)) | 614 | if (initrd_start && (initrd_end > initrd_start)) |