diff options
| -rw-r--r-- | arch/arm/mm/init.c | 42 |
1 files changed, 25 insertions, 17 deletions
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index f68c93bb1fde..8e1edbc6116f 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c | |||
| @@ -148,14 +148,13 @@ static void __init find_limits(struct meminfo *mi, | |||
| 148 | } | 148 | } |
| 149 | } | 149 | } |
| 150 | 150 | ||
| 151 | static void __init arm_bootmem_init(struct meminfo *mi, | 151 | static void __init arm_bootmem_init(unsigned long start_pfn, |
| 152 | unsigned long start_pfn, unsigned long end_pfn) | 152 | unsigned long end_pfn) |
| 153 | { | 153 | { |
| 154 | struct memblock_region *reg; | 154 | struct memblock_region *reg; |
| 155 | unsigned int boot_pages; | 155 | unsigned int boot_pages; |
| 156 | phys_addr_t bitmap; | 156 | phys_addr_t bitmap; |
| 157 | pg_data_t *pgdat; | 157 | pg_data_t *pgdat; |
| 158 | int i; | ||
| 159 | 158 | ||
| 160 | /* | 159 | /* |
| 161 | * Allocate the bootmem bitmap page. This must be in a region | 160 | * Allocate the bootmem bitmap page. This must be in a region |
| @@ -173,22 +172,31 @@ static void __init arm_bootmem_init(struct meminfo *mi, | |||
| 173 | pgdat = NODE_DATA(0); | 172 | pgdat = NODE_DATA(0); |
| 174 | init_bootmem_node(pgdat, __phys_to_pfn(bitmap), start_pfn, end_pfn); | 173 | init_bootmem_node(pgdat, __phys_to_pfn(bitmap), start_pfn, end_pfn); |
| 175 | 174 | ||
| 176 | for_each_bank(i, mi) { | 175 | /* Free the lowmem regions from memblock into bootmem. */ |
| 177 | struct membank *bank = &mi->bank[i]; | 176 | for_each_memblock(memory, reg) { |
| 178 | if (!bank->highmem) | 177 | unsigned long start = memblock_region_memory_base_pfn(reg); |
| 179 | free_bootmem(bank_phys_start(bank), bank_phys_size(bank)); | 178 | unsigned long end = memblock_region_memory_end_pfn(reg); |
| 179 | |||
| 180 | if (end >= end_pfn) | ||
| 181 | end = end_pfn; | ||
| 182 | if (start >= end) | ||
| 183 | break; | ||
| 184 | |||
| 185 | free_bootmem(__pfn_to_phys(start), (end - start) << PAGE_SHIFT); | ||
| 180 | } | 186 | } |
| 181 | 187 | ||
| 182 | /* | 188 | /* Reserve the lowmem memblock reserved regions in bootmem. */ |
| 183 | * Reserve the memblock reserved regions in bootmem. | ||
| 184 | */ | ||
| 185 | for_each_memblock(reserved, reg) { | 189 | for_each_memblock(reserved, reg) { |
| 186 | phys_addr_t start = memblock_region_reserved_base_pfn(reg); | 190 | unsigned long start = memblock_region_reserved_base_pfn(reg); |
| 187 | phys_addr_t end = memblock_region_reserved_end_pfn(reg); | 191 | unsigned long end = memblock_region_reserved_end_pfn(reg); |
| 188 | if (start >= start_pfn && end <= end_pfn) | 192 | |
| 189 | reserve_bootmem_node(pgdat, __pfn_to_phys(start), | 193 | if (end >= end_pfn) |
| 190 | (end - start) << PAGE_SHIFT, | 194 | end = end_pfn; |
| 191 | BOOTMEM_DEFAULT); | 195 | if (start >= end) |
| 196 | break; | ||
| 197 | |||
| 198 | reserve_bootmem(__pfn_to_phys(start), | ||
| 199 | (end - start) << PAGE_SHIFT, BOOTMEM_DEFAULT); | ||
| 192 | } | 200 | } |
| 193 | } | 201 | } |
| 194 | 202 | ||
| @@ -316,7 +324,7 @@ void __init bootmem_init(void) | |||
| 316 | 324 | ||
| 317 | find_limits(mi, &min, &max_low, &max_high); | 325 | find_limits(mi, &min, &max_low, &max_high); |
| 318 | 326 | ||
| 319 | arm_bootmem_init(mi, min, max_low); | 327 | arm_bootmem_init(min, max_low); |
| 320 | 328 | ||
| 321 | /* | 329 | /* |
| 322 | * Sparsemem tries to allocate bootmem in memory_present(), | 330 | * Sparsemem tries to allocate bootmem in memory_present(), |
