msm: do not create memory pools from unstable memory
When reserving memory for memory pools, do not use
memory which can potentially be powered off.
Signed-off-by: Larry Bassel <lbassel@codeaurora.org>
diff --git a/arch/arm/mach-msm/memory.c b/arch/arm/mach-msm/memory.c
index 2ece32e..0e0644b 100644
--- a/arch/arm/mach-msm/memory.c
+++ b/arch/arm/mach-msm/memory.c
@@ -229,12 +229,23 @@
struct reserve_info *reserve_info;
+static unsigned long stable_size(struct membank *mb,
+ unsigned long unstable_limit)
+{
+ if (!unstable_limit || mb->start + mb->size <= unstable_limit)
+ return mb->size;
+ if (mb->start >= unstable_limit)
+ return 0;
+ return unstable_limit - mb->start;
+}
+
static void __init calculate_reserve_limits(void)
{
int i;
struct membank *mb;
int memtype;
struct memtype_reserve *mt;
+ unsigned long size;
for (i = 0, mb = &meminfo.bank[0]; i < meminfo.nr_banks; i++, mb++) {
memtype = reserve_info->paddr_to_memtype(mb->start);
@@ -244,7 +255,8 @@
continue;
}
mt = &reserve_info->memtype_reserve_table[memtype];
- mt->limit = max(mt->limit, mb->size);
+ size = stable_size(mb, reserve_info->low_unstable_address);
+ mt->limit = max(mt->limit, size);
}
}
@@ -271,6 +283,7 @@
struct memtype_reserve *mt;
struct membank *mb;
int ret;
+ unsigned long size;
mt = &reserve_info->memtype_reserve_table[0];
for (memtype = 0; memtype < MEMTYPE_MAX; memtype++, mt++) {
@@ -285,7 +298,7 @@
* take memory from the lowest memory bank which the kernel
* is in (and cause boot problems) and so that we might
* be able to steal memory that would otherwise become
- * highmem.
+ * highmem. However, do not use unstable memory.
*/
for (i = meminfo.nr_banks - 1; i >= 0; i--) {
mb = &meminfo.bank[i];
@@ -293,8 +306,10 @@
reserve_info->paddr_to_memtype(mb->start);
if (memtype != membank_type)
continue;
- if (mb->size >= mt->size) {
- mt->start = mb->start + mb->size - mt->size;
+ size = stable_size(mb,
+ reserve_info->low_unstable_address);
+ if (size >= mt->size) {
+ mt->start = mb->start + size - mt->size;
ret = memblock_remove(mt->start, mt->size);
BUG_ON(ret);
break;