diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-05 18:57:04 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-05 18:57:04 -0400 |
commit | eb3d3ec567e868c8a3bfbfdfc9465ffd52983d11 (patch) | |
tree | 75acf38b8d73cd281e5ce4dcc941faf48e244b98 /arch/arm/mm/init.c | |
parent | c3c55a07203947f72afa50a3218460b27307c47d (diff) | |
parent | bd63ce27d9d62bc40a962b991cbbbe4f0dc913d2 (diff) |
Merge branch 'for-linus' of git://ftp.arm.linux.org.uk/~rmk/linux-arm into next
Pull ARM updates from Russell King:
- Major clean-up of the L2 cache support code. The existing mess was
becoming rather unmaintainable through all the additions that others
have done over time. This turns it into a much nicer structure, and
implements a few performance improvements as well.
- Clean up some of the CP15 control register tweaks for alignment
support, moving some code and data into alignment.c
- DMA properties for ARM, from Santosh and reviewed by DT people. This
adds DT properties to specify bus translations we can't discover
automatically, and to indicate whether devices are coherent.
- Hibernation support for ARM
- Make ftrace work with read-only text in modules
- add suspend support for PJ4B CPUs
- rework interrupt masking for undefined instruction handling, which
allows us to enable interrupts earlier in the handling of these
exceptions.
- support for big endian page tables
- fix stacktrace support to exclude stacktrace functions from the
trace, and add save_stack_trace_regs() implementation so that kprobes
can record stack traces.
- Add support for the Cortex-A17 CPU.
- Remove last vestiges of ARM710 support.
- Removal of ARM "meminfo" structure, finally converting us solely to
memblock to handle the early memory initialisation.
* 'for-linus' of git://ftp.arm.linux.org.uk/~rmk/linux-arm: (142 commits)
ARM: ensure C page table setup code follows assembly code (part II)
ARM: ensure C page table setup code follows assembly code
ARM: consolidate last remaining open-coded alignment trap enable
ARM: remove global cr_no_alignment
ARM: remove CPU_CP15 conditional from alignment.c
ARM: remove unused adjust_cr() function
ARM: move "noalign" command line option to alignment.c
ARM: provide common method to clear bits in CPU control register
ARM: 8025/1: Get rid of meminfo
ARM: 8060/1: mm: allow sub-architectures to override PCI I/O memory type
ARM: 8066/1: correction for ARM patch 8031/2
ARM: 8049/1: ftrace/add save_stack_trace_regs() implementation
ARM: 8065/1: remove last use of CONFIG_CPU_ARM710
ARM: 8062/1: Modify ldrt fixup handler to re-execute the userspace instruction
ARM: 8047/1: rwsem: use asm-generic rwsem implementation
ARM: l2c: trial at enabling some Cortex-A9 optimisations
ARM: l2c: add warnings for stuff modifying aux_ctrl register values
ARM: l2c: print a warning with L2C-310 caches if the cache size is modified
ARM: l2c: remove old .set_debug method
ARM: l2c: kill L2X0_AUX_CTRL_MASK before anyone else makes use of this
...
Diffstat (limited to 'arch/arm/mm/init.c')
-rw-r--r-- | arch/arm/mm/init.c | 81 |
1 files changed, 37 insertions, 44 deletions
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index 928d596d9ab4..659c75d808dc 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/dma-contiguous.h> | 23 | #include <linux/dma-contiguous.h> |
24 | #include <linux/sizes.h> | 24 | #include <linux/sizes.h> |
25 | 25 | ||
26 | #include <asm/cp15.h> | ||
26 | #include <asm/mach-types.h> | 27 | #include <asm/mach-types.h> |
27 | #include <asm/memblock.h> | 28 | #include <asm/memblock.h> |
28 | #include <asm/prom.h> | 29 | #include <asm/prom.h> |
@@ -36,6 +37,14 @@ | |||
36 | 37 | ||
37 | #include "mm.h" | 38 | #include "mm.h" |
38 | 39 | ||
40 | #ifdef CONFIG_CPU_CP15_MMU | ||
41 | unsigned long __init __clear_cr(unsigned long mask) | ||
42 | { | ||
43 | cr_alignment = cr_alignment & ~mask; | ||
44 | return cr_alignment; | ||
45 | } | ||
46 | #endif | ||
47 | |||
39 | static phys_addr_t phys_initrd_start __initdata = 0; | 48 | static phys_addr_t phys_initrd_start __initdata = 0; |
40 | static unsigned long phys_initrd_size __initdata = 0; | 49 | static unsigned long phys_initrd_size __initdata = 0; |
41 | 50 | ||
@@ -81,24 +90,21 @@ __tagtable(ATAG_INITRD2, parse_tag_initrd2); | |||
81 | * initialization functions, as well as show_mem() for the skipping | 90 | * initialization functions, as well as show_mem() for the skipping |
82 | * of holes in the memory map. It is populated by arm_add_memory(). | 91 | * of holes in the memory map. It is populated by arm_add_memory(). |
83 | */ | 92 | */ |
84 | struct meminfo meminfo; | ||
85 | |||
86 | void show_mem(unsigned int filter) | 93 | void show_mem(unsigned int filter) |
87 | { | 94 | { |
88 | int free = 0, total = 0, reserved = 0; | 95 | int free = 0, total = 0, reserved = 0; |
89 | int shared = 0, cached = 0, slab = 0, i; | 96 | int shared = 0, cached = 0, slab = 0; |
90 | struct meminfo * mi = &meminfo; | 97 | struct memblock_region *reg; |
91 | 98 | ||
92 | printk("Mem-info:\n"); | 99 | printk("Mem-info:\n"); |
93 | show_free_areas(filter); | 100 | show_free_areas(filter); |
94 | 101 | ||
95 | for_each_bank (i, mi) { | 102 | for_each_memblock (memory, reg) { |
96 | struct membank *bank = &mi->bank[i]; | ||
97 | unsigned int pfn1, pfn2; | 103 | unsigned int pfn1, pfn2; |
98 | struct page *page, *end; | 104 | struct page *page, *end; |
99 | 105 | ||
100 | pfn1 = bank_pfn_start(bank); | 106 | pfn1 = memblock_region_memory_base_pfn(reg); |
101 | pfn2 = bank_pfn_end(bank); | 107 | pfn2 = memblock_region_memory_end_pfn(reg); |
102 | 108 | ||
103 | page = pfn_to_page(pfn1); | 109 | page = pfn_to_page(pfn1); |
104 | end = pfn_to_page(pfn2 - 1) + 1; | 110 | end = pfn_to_page(pfn2 - 1) + 1; |
@@ -115,8 +121,9 @@ void show_mem(unsigned int filter) | |||
115 | free++; | 121 | free++; |
116 | else | 122 | else |
117 | shared += page_count(page) - 1; | 123 | shared += page_count(page) - 1; |
118 | page++; | 124 | pfn1++; |
119 | } while (page < end); | 125 | page = pfn_to_page(pfn1); |
126 | } while (pfn1 < pfn2); | ||
120 | } | 127 | } |
121 | 128 | ||
122 | printk("%d pages of RAM\n", total); | 129 | printk("%d pages of RAM\n", total); |
@@ -130,16 +137,9 @@ void show_mem(unsigned int filter) | |||
130 | static void __init find_limits(unsigned long *min, unsigned long *max_low, | 137 | static void __init find_limits(unsigned long *min, unsigned long *max_low, |
131 | unsigned long *max_high) | 138 | unsigned long *max_high) |
132 | { | 139 | { |
133 | struct meminfo *mi = &meminfo; | 140 | *max_low = PFN_DOWN(memblock_get_current_limit()); |
134 | int i; | 141 | *min = PFN_UP(memblock_start_of_DRAM()); |
135 | 142 | *max_high = PFN_DOWN(memblock_end_of_DRAM()); | |
136 | /* This assumes the meminfo array is properly sorted */ | ||
137 | *min = bank_pfn_start(&mi->bank[0]); | ||
138 | for_each_bank (i, mi) | ||
139 | if (mi->bank[i].highmem) | ||
140 | break; | ||
141 | *max_low = bank_pfn_end(&mi->bank[i - 1]); | ||
142 | *max_high = bank_pfn_end(&mi->bank[mi->nr_banks - 1]); | ||
143 | } | 143 | } |
144 | 144 | ||
145 | #ifdef CONFIG_ZONE_DMA | 145 | #ifdef CONFIG_ZONE_DMA |
@@ -274,14 +274,8 @@ phys_addr_t __init arm_memblock_steal(phys_addr_t size, phys_addr_t align) | |||
274 | return phys; | 274 | return phys; |
275 | } | 275 | } |
276 | 276 | ||
277 | void __init arm_memblock_init(struct meminfo *mi, | 277 | void __init arm_memblock_init(const struct machine_desc *mdesc) |
278 | const struct machine_desc *mdesc) | ||
279 | { | 278 | { |
280 | int i; | ||
281 | |||
282 | for (i = 0; i < mi->nr_banks; i++) | ||
283 | memblock_add(mi->bank[i].start, mi->bank[i].size); | ||
284 | |||
285 | /* Register the kernel text, kernel data and initrd with memblock. */ | 279 | /* Register the kernel text, kernel data and initrd with memblock. */ |
286 | #ifdef CONFIG_XIP_KERNEL | 280 | #ifdef CONFIG_XIP_KERNEL |
287 | memblock_reserve(__pa(_sdata), _end - _sdata); | 281 | memblock_reserve(__pa(_sdata), _end - _sdata); |
@@ -412,54 +406,53 @@ free_memmap(unsigned long start_pfn, unsigned long end_pfn) | |||
412 | /* | 406 | /* |
413 | * The mem_map array can get very big. Free the unused area of the memory map. | 407 | * The mem_map array can get very big. Free the unused area of the memory map. |
414 | */ | 408 | */ |
415 | static void __init free_unused_memmap(struct meminfo *mi) | 409 | static void __init free_unused_memmap(void) |
416 | { | 410 | { |
417 | unsigned long bank_start, prev_bank_end = 0; | 411 | unsigned long start, prev_end = 0; |
418 | unsigned int i; | 412 | struct memblock_region *reg; |
419 | 413 | ||
420 | /* | 414 | /* |
421 | * This relies on each bank being in address order. | 415 | * This relies on each bank being in address order. |
422 | * The banks are sorted previously in bootmem_init(). | 416 | * The banks are sorted previously in bootmem_init(). |
423 | */ | 417 | */ |
424 | for_each_bank(i, mi) { | 418 | for_each_memblock(memory, reg) { |
425 | struct membank *bank = &mi->bank[i]; | 419 | start = memblock_region_memory_base_pfn(reg); |
426 | |||
427 | bank_start = bank_pfn_start(bank); | ||
428 | 420 | ||
429 | #ifdef CONFIG_SPARSEMEM | 421 | #ifdef CONFIG_SPARSEMEM |
430 | /* | 422 | /* |
431 | * Take care not to free memmap entries that don't exist | 423 | * Take care not to free memmap entries that don't exist |
432 | * due to SPARSEMEM sections which aren't present. | 424 | * due to SPARSEMEM sections which aren't present. |
433 | */ | 425 | */ |
434 | bank_start = min(bank_start, | 426 | start = min(start, |
435 | ALIGN(prev_bank_end, PAGES_PER_SECTION)); | 427 | ALIGN(prev_end, PAGES_PER_SECTION)); |
436 | #else | 428 | #else |
437 | /* | 429 | /* |
438 | * Align down here since the VM subsystem insists that the | 430 | * Align down here since the VM subsystem insists that the |
439 | * memmap entries are valid from the bank start aligned to | 431 | * memmap entries are valid from the bank start aligned to |
440 | * MAX_ORDER_NR_PAGES. | 432 | * MAX_ORDER_NR_PAGES. |
441 | */ | 433 | */ |
442 | bank_start = round_down(bank_start, MAX_ORDER_NR_PAGES); | 434 | start = round_down(start, MAX_ORDER_NR_PAGES); |
443 | #endif | 435 | #endif |
444 | /* | 436 | /* |
445 | * If we had a previous bank, and there is a space | 437 | * If we had a previous bank, and there is a space |
446 | * between the current bank and the previous, free it. | 438 | * between the current bank and the previous, free it. |
447 | */ | 439 | */ |
448 | if (prev_bank_end && prev_bank_end < bank_start) | 440 | if (prev_end && prev_end < start) |
449 | free_memmap(prev_bank_end, bank_start); | 441 | free_memmap(prev_end, start); |
450 | 442 | ||
451 | /* | 443 | /* |
452 | * Align up here since the VM subsystem insists that the | 444 | * Align up here since the VM subsystem insists that the |
453 | * memmap entries are valid from the bank end aligned to | 445 | * memmap entries are valid from the bank end aligned to |
454 | * MAX_ORDER_NR_PAGES. | 446 | * MAX_ORDER_NR_PAGES. |
455 | */ | 447 | */ |
456 | prev_bank_end = ALIGN(bank_pfn_end(bank), MAX_ORDER_NR_PAGES); | 448 | prev_end = ALIGN(memblock_region_memory_end_pfn(reg), |
449 | MAX_ORDER_NR_PAGES); | ||
457 | } | 450 | } |
458 | 451 | ||
459 | #ifdef CONFIG_SPARSEMEM | 452 | #ifdef CONFIG_SPARSEMEM |
460 | if (!IS_ALIGNED(prev_bank_end, PAGES_PER_SECTION)) | 453 | if (!IS_ALIGNED(prev_end, PAGES_PER_SECTION)) |
461 | free_memmap(prev_bank_end, | 454 | free_memmap(prev_end, |
462 | ALIGN(prev_bank_end, PAGES_PER_SECTION)); | 455 | ALIGN(prev_end, PAGES_PER_SECTION)); |
463 | #endif | 456 | #endif |
464 | } | 457 | } |
465 | 458 | ||
@@ -535,7 +528,7 @@ void __init mem_init(void) | |||
535 | set_max_mapnr(pfn_to_page(max_pfn) - mem_map); | 528 | set_max_mapnr(pfn_to_page(max_pfn) - mem_map); |
536 | 529 | ||
537 | /* this will put all unused low memory onto the freelists */ | 530 | /* this will put all unused low memory onto the freelists */ |
538 | free_unused_memmap(&meminfo); | 531 | free_unused_memmap(); |
539 | free_all_bootmem(); | 532 | free_all_bootmem(); |
540 | 533 | ||
541 | #ifdef CONFIG_SA1111 | 534 | #ifdef CONFIG_SA1111 |