Merge branches 'consolidate-clksrc', 'consolidate-flash', 'consolidate-generic',...
[pandora-kernel.git] / arch / arm / mm / init.c
index e5f6fc4..76f82ae 100644 (file)
@@ -201,6 +201,20 @@ static void __init arm_bootmem_init(unsigned long start_pfn,
        }
 }
 
+#ifdef CONFIG_ZONE_DMA
+static void __init arm_adjust_dma_zone(unsigned long *size, unsigned long *hole,
+       unsigned long dma_size)
+{
+       if (size[0] <= dma_size)
+               return;
+
+       size[ZONE_NORMAL] = size[0] - dma_size;
+       size[ZONE_DMA] = dma_size;
+       hole[ZONE_NORMAL] = hole[0];
+       hole[ZONE_DMA] = 0;
+}
+#endif
+
 static void __init arm_bootmem_free(unsigned long min, unsigned long max_low,
        unsigned long max_high)
 {
@@ -243,11 +257,18 @@ static void __init arm_bootmem_free(unsigned long min, unsigned long max_low,
 #endif
        }
 
+#ifdef ARM_DMA_ZONE_SIZE
+#ifndef CONFIG_ZONE_DMA
+#error ARM_DMA_ZONE_SIZE set but no DMA zone to limit allocations
+#endif
+
        /*
         * Adjust the sizes according to any special requirements for
         * this machine type.
         */
-       arch_adjust_zones(zone_size, zhole_size);
+       arm_adjust_dma_zone(zone_size, zhole_size,
+               ARM_DMA_ZONE_SIZE >> PAGE_SHIFT);
+#endif
 
        free_area_init_node(0, zone_size, min, zhole_size);
 }
@@ -392,7 +413,7 @@ free_memmap(unsigned long start_pfn, unsigned long end_pfn)
         * Convert start_pfn/end_pfn to a struct page pointer.
         */
        start_pg = pfn_to_page(start_pfn - 1) + 1;
-       end_pg = pfn_to_page(end_pfn);
+       end_pg = pfn_to_page(end_pfn - 1) + 1;
 
        /*
         * Convert to physical addresses, and
@@ -426,6 +447,14 @@ static void __init free_unused_memmap(struct meminfo *mi)
 
                bank_start = bank_pfn_start(bank);
 
+#ifdef CONFIG_SPARSEMEM
+               /*
+                * Take care not to free memmap entries that don't exist
+                * due to SPARSEMEM sections which aren't present.
+                */
+               bank_start = min(bank_start,
+                                ALIGN(prev_bank_end, PAGES_PER_SECTION));
+#endif
                /*
                 * If we had a previous bank, and there is a space
                 * between the current bank and the previous, free it.
@@ -440,6 +469,12 @@ static void __init free_unused_memmap(struct meminfo *mi)
                 */
                prev_bank_end = ALIGN(bank_pfn_end(bank), MAX_ORDER_NR_PAGES);
        }
+
+#ifdef CONFIG_SPARSEMEM
+       if (!IS_ALIGNED(prev_bank_end, PAGES_PER_SECTION))
+               free_memmap(prev_bank_end,
+                           ALIGN(prev_bank_end, PAGES_PER_SECTION));
+#endif
 }
 
 static void __init free_highpages(void)