aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/Kconfig12
-rw-r--r--arch/arm/boot/compressed/Makefile3
-rw-r--r--arch/arm/boot/dts/exynos5250-pinctrl.dtsi2
-rw-r--r--arch/arm/boot/dts/exynos5250.dtsi4
-rw-r--r--arch/arm/include/asm/cacheflush.h4
-rw-r--r--arch/arm/kernel/machine_kexec.c4
-rw-r--r--arch/arm/kernel/process.c43
-rw-r--r--arch/arm/kernel/smp.c13
-rw-r--r--arch/arm/mm/cache-v7.S8
-rw-r--r--arch/arm/mm/flush.c33
-rw-r--r--arch/arm/mm/mmu.c8
-rw-r--r--arch/arm/mm/proc-v7.S4
12 files changed, 106 insertions, 32 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 49d993cee512..2651b1da1c56 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1189,6 +1189,16 @@ config PL310_ERRATA_588369
1189 is not correctly implemented in PL310 as clean lines are not 1189 is not correctly implemented in PL310 as clean lines are not
1190 invalidated as a result of these operations. 1190 invalidated as a result of these operations.
1191 1191
1192config ARM_ERRATA_643719
1193 bool "ARM errata: LoUIS bit field in CLIDR register is incorrect"
1194 depends on CPU_V7 && SMP
1195 help
1196 This option enables the workaround for the 643719 Cortex-A9 (prior to
1197 r1p0) erratum. On affected cores the LoUIS bit field of the CLIDR
1198 register returns zero when it should return one. The workaround
1199 corrects this value, ensuring cache maintenance operations which use
1200 it behave as intended and avoiding data corruption.
1201
1192config ARM_ERRATA_720789 1202config ARM_ERRATA_720789
1193 bool "ARM errata: TLBIASIDIS and TLBIMVAIS operations can broadcast a faulty ASID" 1203 bool "ARM errata: TLBIASIDIS and TLBIMVAIS operations can broadcast a faulty ASID"
1194 depends on CPU_V7 1204 depends on CPU_V7
@@ -2006,7 +2016,7 @@ config XIP_PHYS_ADDR
2006 2016
2007config KEXEC 2017config KEXEC
2008 bool "Kexec system call (EXPERIMENTAL)" 2018 bool "Kexec system call (EXPERIMENTAL)"
2009 depends on (!SMP || HOTPLUG_CPU) 2019 depends on (!SMP || PM_SLEEP_SMP)
2010 help 2020 help
2011 kexec is a system call that implements the ability to shutdown your 2021 kexec is a system call that implements the ability to shutdown your
2012 current kernel, and to start another kernel. It is like a reboot 2022 current kernel, and to start another kernel. It is like a reboot
diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
index 79e9bdbfc491..120b83bfde20 100644
--- a/arch/arm/boot/compressed/Makefile
+++ b/arch/arm/boot/compressed/Makefile
@@ -116,7 +116,8 @@ targets := vmlinux vmlinux.lds \
116 116
117# Make sure files are removed during clean 117# Make sure files are removed during clean
118extra-y += piggy.gzip piggy.lzo piggy.lzma piggy.xzkern \ 118extra-y += piggy.gzip piggy.lzo piggy.lzma piggy.xzkern \
119 lib1funcs.S ashldi3.S $(libfdt) $(libfdt_hdrs) 119 lib1funcs.S ashldi3.S $(libfdt) $(libfdt_hdrs) \
120 hyp-stub.S
120 121
121ifeq ($(CONFIG_FUNCTION_TRACER),y) 122ifeq ($(CONFIG_FUNCTION_TRACER),y)
122ORIG_CFLAGS := $(KBUILD_CFLAGS) 123ORIG_CFLAGS := $(KBUILD_CFLAGS)
diff --git a/arch/arm/boot/dts/exynos5250-pinctrl.dtsi b/arch/arm/boot/dts/exynos5250-pinctrl.dtsi
index d1650fb34c0a..ded558bb0f3b 100644
--- a/arch/arm/boot/dts/exynos5250-pinctrl.dtsi
+++ b/arch/arm/boot/dts/exynos5250-pinctrl.dtsi
@@ -763,7 +763,7 @@
763 }; 763 };
764 }; 764 };
765 765
766 pinctrl@03680000 { 766 pinctrl@03860000 {
767 gpz: gpz { 767 gpz: gpz {
768 gpio-controller; 768 gpio-controller;
769 #gpio-cells = <2>; 769 #gpio-cells = <2>;
diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi
index 0673524238a6..fc9fb3d526e2 100644
--- a/arch/arm/boot/dts/exynos5250.dtsi
+++ b/arch/arm/boot/dts/exynos5250.dtsi
@@ -161,9 +161,9 @@
161 interrupts = <0 50 0>; 161 interrupts = <0 50 0>;
162 }; 162 };
163 163
164 pinctrl_3: pinctrl@03680000 { 164 pinctrl_3: pinctrl@03860000 {
165 compatible = "samsung,exynos5250-pinctrl"; 165 compatible = "samsung,exynos5250-pinctrl";
166 reg = <0x0368000 0x1000>; 166 reg = <0x03860000 0x1000>;
167 interrupts = <0 47 0>; 167 interrupts = <0 47 0>;
168 }; 168 };
169 169
diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h
index bff71388e72a..17d0ae8672fa 100644
--- a/arch/arm/include/asm/cacheflush.h
+++ b/arch/arm/include/asm/cacheflush.h
@@ -320,9 +320,7 @@ static inline void flush_anon_page(struct vm_area_struct *vma,
320} 320}
321 321
322#define ARCH_HAS_FLUSH_KERNEL_DCACHE_PAGE 322#define ARCH_HAS_FLUSH_KERNEL_DCACHE_PAGE
323static inline void flush_kernel_dcache_page(struct page *page) 323extern void flush_kernel_dcache_page(struct page *);
324{
325}
326 324
327#define flush_dcache_mmap_lock(mapping) \ 325#define flush_dcache_mmap_lock(mapping) \
328 spin_lock_irq(&(mapping)->tree_lock) 326 spin_lock_irq(&(mapping)->tree_lock)
diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c
index 8ef8c9337809..4fb074c446bf 100644
--- a/arch/arm/kernel/machine_kexec.c
+++ b/arch/arm/kernel/machine_kexec.c
@@ -134,6 +134,10 @@ void machine_kexec(struct kimage *image)
134 unsigned long reboot_code_buffer_phys; 134 unsigned long reboot_code_buffer_phys;
135 void *reboot_code_buffer; 135 void *reboot_code_buffer;
136 136
137 if (num_online_cpus() > 1) {
138 pr_err("kexec: error: multiple CPUs still online\n");
139 return;
140 }
137 141
138 page_list = image->head & PAGE_MASK; 142 page_list = image->head & PAGE_MASK;
139 143
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 282de4826abb..6e8931ccf13e 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -184,30 +184,61 @@ int __init reboot_setup(char *str)
184 184
185__setup("reboot=", reboot_setup); 185__setup("reboot=", reboot_setup);
186 186
187/*
188 * Called by kexec, immediately prior to machine_kexec().
189 *
190 * This must completely disable all secondary CPUs; simply causing those CPUs
191 * to execute e.g. a RAM-based pin loop is not sufficient. This allows the
192 * kexec'd kernel to use any and all RAM as it sees fit, without having to
193 * avoid any code or data used by any SW CPU pin loop. The CPU hotplug
194 * functionality embodied in disable_nonboot_cpus() to achieve this.
195 */
187void machine_shutdown(void) 196void machine_shutdown(void)
188{ 197{
189#ifdef CONFIG_SMP 198 disable_nonboot_cpus();
190 smp_send_stop();
191#endif
192} 199}
193 200
201/*
202 * Halting simply requires that the secondary CPUs stop performing any
203 * activity (executing tasks, handling interrupts). smp_send_stop()
204 * achieves this.
205 */
194void machine_halt(void) 206void machine_halt(void)
195{ 207{
196 machine_shutdown(); 208 smp_send_stop();
209
197 local_irq_disable(); 210 local_irq_disable();
198 while (1); 211 while (1);
199} 212}
200 213
214/*
215 * Power-off simply requires that the secondary CPUs stop performing any
216 * activity (executing tasks, handling interrupts). smp_send_stop()
217 * achieves this. When the system power is turned off, it will take all CPUs
218 * with it.
219 */
201void machine_power_off(void) 220void machine_power_off(void)
202{ 221{
203 machine_shutdown(); 222 smp_send_stop();
223
204 if (pm_power_off) 224 if (pm_power_off)
205 pm_power_off(); 225 pm_power_off();
206} 226}
207 227
228/*
229 * Restart requires that the secondary CPUs stop performing any activity
230 * while the primary CPU resets the system. Systems with a single CPU can
231 * use soft_restart() as their machine descriptor's .restart hook, since that
232 * will cause the only available CPU to reset. Systems with multiple CPUs must
233 * provide a HW restart implementation, to ensure that all CPUs reset at once.
234 * This is required so that any code running after reset on the primary CPU
235 * doesn't have to co-ordinate with other CPUs to ensure they aren't still
236 * executing pre-reset code, and using RAM that the primary CPU's code wishes
237 * to use. Implementing such co-ordination would be essentially impossible.
238 */
208void machine_restart(char *cmd) 239void machine_restart(char *cmd)
209{ 240{
210 machine_shutdown(); 241 smp_send_stop();
211 242
212 arm_pm_restart(reboot_mode, cmd); 243 arm_pm_restart(reboot_mode, cmd);
213 244
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 550d63cef68e..5919eb451bb9 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -651,17 +651,6 @@ void smp_send_reschedule(int cpu)
651 smp_cross_call(cpumask_of(cpu), IPI_RESCHEDULE); 651 smp_cross_call(cpumask_of(cpu), IPI_RESCHEDULE);
652} 652}
653 653
654#ifdef CONFIG_HOTPLUG_CPU
655static void smp_kill_cpus(cpumask_t *mask)
656{
657 unsigned int cpu;
658 for_each_cpu(cpu, mask)
659 platform_cpu_kill(cpu);
660}
661#else
662static void smp_kill_cpus(cpumask_t *mask) { }
663#endif
664
665void smp_send_stop(void) 654void smp_send_stop(void)
666{ 655{
667 unsigned long timeout; 656 unsigned long timeout;
@@ -679,8 +668,6 @@ void smp_send_stop(void)
679 668
680 if (num_online_cpus() > 1) 669 if (num_online_cpus() > 1)
681 pr_warning("SMP: failed to stop secondary CPUs\n"); 670 pr_warning("SMP: failed to stop secondary CPUs\n");
682
683 smp_kill_cpus(&mask);
684} 671}
685 672
686/* 673/*
diff --git a/arch/arm/mm/cache-v7.S b/arch/arm/mm/cache-v7.S
index 15451ee4acc8..515b00064da8 100644
--- a/arch/arm/mm/cache-v7.S
+++ b/arch/arm/mm/cache-v7.S
@@ -92,6 +92,14 @@ ENTRY(v7_flush_dcache_louis)
92 mrc p15, 1, r0, c0, c0, 1 @ read clidr, r0 = clidr 92 mrc p15, 1, r0, c0, c0, 1 @ read clidr, r0 = clidr
93 ALT_SMP(ands r3, r0, #(7 << 21)) @ extract LoUIS from clidr 93 ALT_SMP(ands r3, r0, #(7 << 21)) @ extract LoUIS from clidr
94 ALT_UP(ands r3, r0, #(7 << 27)) @ extract LoUU from clidr 94 ALT_UP(ands r3, r0, #(7 << 27)) @ extract LoUU from clidr
95#ifdef CONFIG_ARM_ERRATA_643719
96 ALT_SMP(mrceq p15, 0, r2, c0, c0, 0) @ read main ID register
97 ALT_UP(moveq pc, lr) @ LoUU is zero, so nothing to do
98 ldreq r1, =0x410fc090 @ ID of ARM Cortex A9 r0p?
99 biceq r2, r2, #0x0000000f @ clear minor revision number
100 teqeq r2, r1 @ test for errata affected core and if so...
101 orreqs r3, #(1 << 21) @ fix LoUIS value (and set flags state to 'ne')
102#endif
95 ALT_SMP(mov r3, r3, lsr #20) @ r3 = LoUIS * 2 103 ALT_SMP(mov r3, r3, lsr #20) @ r3 = LoUIS * 2
96 ALT_UP(mov r3, r3, lsr #26) @ r3 = LoUU * 2 104 ALT_UP(mov r3, r3, lsr #26) @ r3 = LoUU * 2
97 moveq pc, lr @ return if level == 0 105 moveq pc, lr @ return if level == 0
diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c
index 0d473cce501c..32aa5861119f 100644
--- a/arch/arm/mm/flush.c
+++ b/arch/arm/mm/flush.c
@@ -301,6 +301,39 @@ void flush_dcache_page(struct page *page)
301EXPORT_SYMBOL(flush_dcache_page); 301EXPORT_SYMBOL(flush_dcache_page);
302 302
303/* 303/*
304 * Ensure cache coherency for the kernel mapping of this page. We can
305 * assume that the page is pinned via kmap.
306 *
307 * If the page only exists in the page cache and there are no user
308 * space mappings, this is a no-op since the page was already marked
309 * dirty at creation. Otherwise, we need to flush the dirty kernel
310 * cache lines directly.
311 */
312void flush_kernel_dcache_page(struct page *page)
313{
314 if (cache_is_vivt() || cache_is_vipt_aliasing()) {
315 struct address_space *mapping;
316
317 mapping = page_mapping(page);
318
319 if (!mapping || mapping_mapped(mapping)) {
320 void *addr;
321
322 addr = page_address(page);
323 /*
324 * kmap_atomic() doesn't set the page virtual
325 * address for highmem pages, and
326 * kunmap_atomic() takes care of cache
327 * flushing already.
328 */
329 if (!IS_ENABLED(CONFIG_HIGHMEM) || addr)
330 __cpuc_flush_dcache_area(addr, PAGE_SIZE);
331 }
332 }
333}
334EXPORT_SYMBOL(flush_kernel_dcache_page);
335
336/*
304 * Flush an anonymous page so that users of get_user_pages() 337 * Flush an anonymous page so that users of get_user_pages()
305 * can safely access the data. The expected sequence is: 338 * can safely access the data. The expected sequence is:
306 * 339 *
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index e0d8565671a6..4d409e6a552d 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -616,10 +616,12 @@ static void __init alloc_init_pte(pmd_t *pmd, unsigned long addr,
616 } while (pte++, addr += PAGE_SIZE, addr != end); 616 } while (pte++, addr += PAGE_SIZE, addr != end);
617} 617}
618 618
619static void __init map_init_section(pmd_t *pmd, unsigned long addr, 619static void __init __map_init_section(pmd_t *pmd, unsigned long addr,
620 unsigned long end, phys_addr_t phys, 620 unsigned long end, phys_addr_t phys,
621 const struct mem_type *type) 621 const struct mem_type *type)
622{ 622{
623 pmd_t *p = pmd;
624
623#ifndef CONFIG_ARM_LPAE 625#ifndef CONFIG_ARM_LPAE
624 /* 626 /*
625 * In classic MMU format, puds and pmds are folded in to 627 * In classic MMU format, puds and pmds are folded in to
@@ -638,7 +640,7 @@ static void __init map_init_section(pmd_t *pmd, unsigned long addr,
638 phys += SECTION_SIZE; 640 phys += SECTION_SIZE;
639 } while (pmd++, addr += SECTION_SIZE, addr != end); 641 } while (pmd++, addr += SECTION_SIZE, addr != end);
640 642
641 flush_pmd_entry(pmd); 643 flush_pmd_entry(p);
642} 644}
643 645
644static void __init alloc_init_pmd(pud_t *pud, unsigned long addr, 646static void __init alloc_init_pmd(pud_t *pud, unsigned long addr,
@@ -661,7 +663,7 @@ static void __init alloc_init_pmd(pud_t *pud, unsigned long addr,
661 */ 663 */
662 if (type->prot_sect && 664 if (type->prot_sect &&
663 ((addr | next | phys) & ~SECTION_MASK) == 0) { 665 ((addr | next | phys) & ~SECTION_MASK) == 0) {
664 map_init_section(pmd, addr, next, phys, type); 666 __map_init_section(pmd, addr, next, phys, type);
665 } else { 667 } else {
666 alloc_init_pte(pmd, addr, next, 668 alloc_init_pte(pmd, addr, next,
667 __phys_to_pfn(phys), type); 669 __phys_to_pfn(phys), type);
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index 2c73a7301ff7..4c8c9c10a388 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -409,8 +409,8 @@ __v7_ca9mp_proc_info:
409 */ 409 */
410 .type __v7_pj4b_proc_info, #object 410 .type __v7_pj4b_proc_info, #object
411__v7_pj4b_proc_info: 411__v7_pj4b_proc_info:
412 .long 0x562f5840 412 .long 0x560f5800
413 .long 0xfffffff0 413 .long 0xff0fff00
414 __v7_proc __v7_pj4b_setup 414 __v7_proc __v7_pj4b_setup
415 .size __v7_pj4b_proc_info, . - __v7_pj4b_proc_info 415 .size __v7_pj4b_proc_info, . - __v7_pj4b_proc_info
416 416