arm: add support for DONT_MAP_HOLE_AFTER_MEMBANK0
Some platforms have memory at the top of the
first memory bank which the kernel cannot
access. Mapping this is unnecessary and wastes
precious virtual space.
Signed-off-by: Larry Bassel <lbassel@codeaurora.org>
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 0078590..4111f91 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1596,6 +1596,10 @@
def_bool y
depends on MEMORY_HOTPLUG
+config DONT_MAP_HOLE_AFTER_MEMBANK0
+ def_bool n
+ depends on SPARSEMEM
+
config FORCE_MAX_ZONEORDER
int "Maximum zone order" if ARCH_SHMOBILE
range 11 64 if ARCH_SHMOBILE
diff --git a/arch/arm/mach-msm/include/mach/memory.h b/arch/arm/mach-msm/include/mach/memory.h
index 9f4788a..f208d88 100644
--- a/arch/arm/mach-msm/include/mach/memory.h
+++ b/arch/arm/mach-msm/include/mach/memory.h
@@ -88,6 +88,27 @@
#define finish_arch_switch(prev) do { store_ttbr0(); } while (0)
#endif
+#ifdef CONFIG_DONT_MAP_HOLE_AFTER_MEMBANK0
+extern unsigned long membank0_size;
+extern unsigned long membank1_start;
+
+#define MEMBANK0_PHYS_OFFSET PHYS_OFFSET
+#define MEMBANK0_PAGE_OFFSET PAGE_OFFSET
+
+#define MEMBANK1_PHYS_OFFSET (membank1_start)
+#define MEMBANK1_PAGE_OFFSET (MEMBANK0_PAGE_OFFSET + (membank0_size))
+
+#define __phys_to_virt(phys) \
+ ((MEMBANK1_PHYS_OFFSET && ((phys) >= MEMBANK1_PHYS_OFFSET)) ? \
+ (phys) - MEMBANK1_PHYS_OFFSET + MEMBANK1_PAGE_OFFSET : \
+ (phys) - MEMBANK0_PHYS_OFFSET + MEMBANK0_PAGE_OFFSET)
+
+#define __virt_to_phys(virt) \
+ ((MEMBANK1_PHYS_OFFSET && ((virt) >= MEMBANK1_PAGE_OFFSET)) ? \
+ (virt) - MEMBANK1_PAGE_OFFSET + MEMBANK1_PHYS_OFFSET : \
+ (virt) - MEMBANK0_PAGE_OFFSET + MEMBANK0_PHYS_OFFSET)
+#endif
+
#endif
#if defined CONFIG_ARCH_MSM_SCORPION || defined CONFIG_ARCH_MSM_KRAIT
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 2cff9aa..052363a 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -313,6 +313,13 @@
return cmp < 0 ? -1 : cmp > 0 ? 1 : 0;
}
+#ifdef CONFIG_DONT_MAP_HOLE_AFTER_MEMBANK0
+unsigned long membank0_size;
+EXPORT_SYMBOL(membank0_size);
+unsigned long membank1_start;
+EXPORT_SYMBOL(membank1_start);
+#endif
+
void __init arm_memblock_init(struct meminfo *mi, struct machine_desc *mdesc)
{
int i;
@@ -323,6 +330,11 @@
for (i = 0; i < mi->nr_banks; i++)
memblock_add(mi->bank[i].start, mi->bank[i].size);
+#ifdef CONFIG_DONT_MAP_HOLE_AFTER_MEMBANK0
+ membank0_size = meminfo.bank[0].size;
+ membank1_start = meminfo.bank[1].start;
+#endif
+
/* Register the kernel text, kernel data and initrd with memblock. */
#ifdef CONFIG_XIP_KERNEL
memblock_reserve(__pa(_sdata), _end - _sdata);