msm: Update meminfo to reflect consecutive memory holes

The device tree now has a node for each of the memory regions
belonging to the subsystems. The meminfo blocks are updated to
reflect these memory holes in such a way that every meminfo block
is of a non-zero size. The start and end of the largest memory
hole is calculated using the meminfo.

Change-Id: I9eb9984f9d74cf2a493846cb2ae7f83db9f92719
Signed-off-by: Neeti Desai <neetid@codeaurora.org>
diff --git a/arch/arm/mach-msm/memory.c b/arch/arm/mach-msm/memory.c
index 1680993..d7d3081 100644
--- a/arch/arm/mach-msm/memory.c
+++ b/arch/arm/mach-msm/memory.c
@@ -384,7 +384,28 @@
 	return 0;
 }
 
-/* This function scans the device tree to populate the memory hole table */
+/* Function to remove any meminfo blocks which are of size zero */
+static void merge_meminfo(void)
+{
+	int i = 0;
+
+	while (i < meminfo.nr_banks) {
+		struct membank *bank = &meminfo.bank[i];
+
+		if (bank->size == 0) {
+			memmove(bank, bank + 1,
+			(meminfo.nr_banks - i) * sizeof(*bank));
+			meminfo.nr_banks--;
+			continue;
+		}
+		i++;
+	}
+}
+
+/*
+ * Function to scan the device tree and adjust the meminfo table to
+ * reflect the memory holes.
+ */
 int __init dt_scan_for_memory_hole(unsigned long node, const char *uname,
 		int depth, void *data)
 {
@@ -413,16 +434,6 @@
 		hole_start = be32_to_cpu(memory_remove_prop[0]);
 		hole_size = be32_to_cpu(memory_remove_prop[1]);
 
-		if (hole_start + hole_size <= MAX_HOLE_ADDRESS) {
-			if (memory_hole_start == 0 && memory_hole_end == 0) {
-				memory_hole_start = hole_start;
-				memory_hole_end = hole_start + hole_size;
-			} else if ((memory_hole_end - memory_hole_start)
-							<= hole_size) {
-				memory_hole_start = hole_start;
-				memory_hole_end = hole_start + hole_size;
-			}
-		}
 		adjust_meminfo(hole_start, hole_size);
 	}
 
@@ -452,6 +463,7 @@
 			bank[1].start = (start + size);
 			bank[1].size -= (bank->size + size);
 			bank[1].highmem = 0;
+			merge_meminfo();
 		}
 	}
 }
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 26b92d4..34cb153 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -395,32 +395,29 @@
 	unsigned long hole_end_virt;
 
 	/*
-	 * Find the start and end of the hole, using meminfo
-	 * if it hasnt been found already.
+	 * Find the start and end of the hole, using meminfo.
 	 */
-	if (memory_hole_start == 0 && memory_hole_end == 0) {
-		for (i = 0; i < (meminfo.nr_banks - 1); i++) {
-			if ((meminfo.bank[i].start + meminfo.bank[i].size) !=
+	for (i = 0; i < (meminfo.nr_banks - 1); i++) {
+		if ((meminfo.bank[i].start + meminfo.bank[i].size) !=
 						meminfo.bank[i+1].start) {
-				if (meminfo.bank[i].start + meminfo.bank[i].size
+			if (meminfo.bank[i].start + meminfo.bank[i].size
 							<= MAX_HOLE_ADDRESS) {
 
-					hole_start = meminfo.bank[i].start +
+				hole_start = meminfo.bank[i].start +
 							meminfo.bank[i].size;
-					hole_size = meminfo.bank[i+1].start -
+				hole_size = meminfo.bank[i+1].start -
 								hole_start;
 
-					if (memory_hole_start == 0 &&
+				if (memory_hole_start == 0 &&
 							memory_hole_end == 0) {
-						memory_hole_start = hole_start;
-						memory_hole_end = hole_start +
+					memory_hole_start = hole_start;
+					memory_hole_end = hole_start +
 								hole_size;
-					} else if ((memory_hole_end -
+				} else if ((memory_hole_end -
 					memory_hole_start) <= hole_size) {
-						memory_hole_start = hole_start;
-						memory_hole_end = hole_start +
+					memory_hole_start = hole_start;
+					memory_hole_end = hole_start +
 								hole_size;
-					}
 				}
 			}
 		}