diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-09-05 21:07:32 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-09-05 21:07:32 -0400 |
commit | 2e032852245b3dcfe5461d7353e34eb6da095ccf (patch) | |
tree | 69f9fdf03b54d76bb539096e0ec96e91ea8216b1 /arch/arm/kernel | |
parent | 356f9e74ffaafd11741589a9aa21d6c9d2721417 (diff) | |
parent | 141b97433d77e39ac3ac111a7b3852192035259c (diff) |
Merge branch 'for-linus' of git://git.linaro.org/people/rmk/linux-arm
Pull ARM updates from Russell King:
"This set includes adding support for Neon acceleration of RAID6 XOR
code from Ard Biesheuvel, cache flushing and barrier updates from Will
Deacon, and a cleanup to the ARM debug code which reduces the amount
of code by about 500 lines.
A few other cleanups, such as constifying the machine descriptors
which already shouldn't be written to, cleaning up the printing of the
L2 cache size"
* 'for-linus' of git://git.linaro.org/people/rmk/linux-arm: (55 commits)
ARM: 7826/1: debug: support debug ll on hisilicon soc
ARM: 7830/1: delay: don't bother reporting bogomips in /proc/cpuinfo
ARM: 7829/1: Add ".text.unlikely" and ".text.hot" to arm unwind tables
ARM: 7828/1: ARMv7-M: implement restart routine common to all v7-M machines
ARM: 7827/1: highbank: fix debug uart virtual address for LPAE
ARM: 7823/1: errata: workaround Cortex-A15 erratum 773022
ARM: 7806/1: allow DEBUG_UNCOMPRESS for Tegra
ARM: 7793/1: debug: use generic option for ep93xx PL10x debug port
ARM: debug: move SPEAr debug to generic PL01x code
ARM: debug: move davinci debug to generic 8250 code
ARM: debug: move keystone debug to generic 8250 code
ARM: debug: remove DEBUG_ROCKCHIP_UART
ARM: debug: provide generic option choices for 8250 and PL01x ports
ARM: debug: move PL01X debug include into arch/arm/include/debug/
ARM: debug: provide PL01x debug uart phys/virt address configuration options
ARM: debug: add support for word accesses to debug/8250.S
ARM: debug: move 8250 debug include into arch/arm/include/debug/
ARM: debug: provide 8250 debug uart phys/virt address configuration options
ARM: debug: provide 8250 debug uart register shift configuration option
ARM: debug: provide 8250 debug uart flow control configuration option
...
Diffstat (limited to 'arch/arm/kernel')
-rw-r--r-- | arch/arm/kernel/Makefile | 2 | ||||
-rw-r--r-- | arch/arm/kernel/atags.h | 5 | ||||
-rw-r--r-- | arch/arm/kernel/atags_parse.c | 6 | ||||
-rw-r--r-- | arch/arm/kernel/devtree.c | 6 | ||||
-rw-r--r-- | arch/arm/kernel/entry-common.S | 4 | ||||
-rw-r--r-- | arch/arm/kernel/module.c | 8 | ||||
-rw-r--r-- | arch/arm/kernel/perf_event_cpu.c | 3 | ||||
-rw-r--r-- | arch/arm/kernel/setup.c | 21 | ||||
-rw-r--r-- | arch/arm/kernel/smp.c | 13 | ||||
-rw-r--r-- | arch/arm/kernel/smp_tlb.c | 10 | ||||
-rw-r--r-- | arch/arm/kernel/traps.c | 66 | ||||
-rw-r--r-- | arch/arm/kernel/v7m.c | 19 |
12 files changed, 105 insertions, 58 deletions
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index 86d10dd47dc4..5140df5f23aa 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile | |||
@@ -24,7 +24,7 @@ obj-$(CONFIG_ATAGS_PROC) += atags_proc.o | |||
24 | obj-$(CONFIG_DEPRECATED_PARAM_STRUCT) += atags_compat.o | 24 | obj-$(CONFIG_DEPRECATED_PARAM_STRUCT) += atags_compat.o |
25 | 25 | ||
26 | ifeq ($(CONFIG_CPU_V7M),y) | 26 | ifeq ($(CONFIG_CPU_V7M),y) |
27 | obj-y += entry-v7m.o | 27 | obj-y += entry-v7m.o v7m.o |
28 | else | 28 | else |
29 | obj-y += entry-armv.o | 29 | obj-y += entry-armv.o |
30 | endif | 30 | endif |
diff --git a/arch/arm/kernel/atags.h b/arch/arm/kernel/atags.h index 9edc9692332d..ec4164da6e30 100644 --- a/arch/arm/kernel/atags.h +++ b/arch/arm/kernel/atags.h | |||
@@ -7,9 +7,10 @@ static inline void save_atags(struct tag *tags) { } | |||
7 | void convert_to_tag_list(struct tag *tags); | 7 | void convert_to_tag_list(struct tag *tags); |
8 | 8 | ||
9 | #ifdef CONFIG_ATAGS | 9 | #ifdef CONFIG_ATAGS |
10 | struct machine_desc *setup_machine_tags(phys_addr_t __atags_pointer, unsigned int machine_nr); | 10 | const struct machine_desc *setup_machine_tags(phys_addr_t __atags_pointer, |
11 | unsigned int machine_nr); | ||
11 | #else | 12 | #else |
12 | static inline struct machine_desc * | 13 | static inline const struct machine_desc * |
13 | setup_machine_tags(phys_addr_t __atags_pointer, unsigned int machine_nr) | 14 | setup_machine_tags(phys_addr_t __atags_pointer, unsigned int machine_nr) |
14 | { | 15 | { |
15 | early_print("no ATAGS support: can't continue\n"); | 16 | early_print("no ATAGS support: can't continue\n"); |
diff --git a/arch/arm/kernel/atags_parse.c b/arch/arm/kernel/atags_parse.c index 14512e6931d8..8c14de8180c0 100644 --- a/arch/arm/kernel/atags_parse.c +++ b/arch/arm/kernel/atags_parse.c | |||
@@ -178,11 +178,11 @@ static void __init squash_mem_tags(struct tag *tag) | |||
178 | tag->hdr.tag = ATAG_NONE; | 178 | tag->hdr.tag = ATAG_NONE; |
179 | } | 179 | } |
180 | 180 | ||
181 | struct machine_desc * __init setup_machine_tags(phys_addr_t __atags_pointer, | 181 | const struct machine_desc * __init |
182 | unsigned int machine_nr) | 182 | setup_machine_tags(phys_addr_t __atags_pointer, unsigned int machine_nr) |
183 | { | 183 | { |
184 | struct tag *tags = (struct tag *)&default_tags; | 184 | struct tag *tags = (struct tag *)&default_tags; |
185 | struct machine_desc *mdesc = NULL, *p; | 185 | const struct machine_desc *mdesc = NULL, *p; |
186 | char *from = default_command_line; | 186 | char *from = default_command_line; |
187 | 187 | ||
188 | default_tags.mem.start = PHYS_OFFSET; | 188 | default_tags.mem.start = PHYS_OFFSET; |
diff --git a/arch/arm/kernel/devtree.c b/arch/arm/kernel/devtree.c index 2ee8a17d2b01..f35906b3d8c9 100644 --- a/arch/arm/kernel/devtree.c +++ b/arch/arm/kernel/devtree.c | |||
@@ -181,10 +181,10 @@ bool arch_match_cpu_phys_id(int cpu, u64 phys_id) | |||
181 | * If a dtb was passed to the kernel in r2, then use it to choose the | 181 | * If a dtb was passed to the kernel in r2, then use it to choose the |
182 | * correct machine_desc and to setup the system. | 182 | * correct machine_desc and to setup the system. |
183 | */ | 183 | */ |
184 | struct machine_desc * __init setup_machine_fdt(unsigned int dt_phys) | 184 | const struct machine_desc * __init setup_machine_fdt(unsigned int dt_phys) |
185 | { | 185 | { |
186 | struct boot_param_header *devtree; | 186 | struct boot_param_header *devtree; |
187 | struct machine_desc *mdesc, *mdesc_best = NULL; | 187 | const struct machine_desc *mdesc, *mdesc_best = NULL; |
188 | unsigned int score, mdesc_score = ~1; | 188 | unsigned int score, mdesc_score = ~1; |
189 | unsigned long dt_root; | 189 | unsigned long dt_root; |
190 | const char *model; | 190 | const char *model; |
@@ -193,7 +193,7 @@ struct machine_desc * __init setup_machine_fdt(unsigned int dt_phys) | |||
193 | DT_MACHINE_START(GENERIC_DT, "Generic DT based system") | 193 | DT_MACHINE_START(GENERIC_DT, "Generic DT based system") |
194 | MACHINE_END | 194 | MACHINE_END |
195 | 195 | ||
196 | mdesc_best = (struct machine_desc *)&__mach_desc_GENERIC_DT; | 196 | mdesc_best = &__mach_desc_GENERIC_DT; |
197 | #endif | 197 | #endif |
198 | 198 | ||
199 | if (!dt_phys) | 199 | if (!dt_phys) |
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S index 94104bf69719..74ad15d1a065 100644 --- a/arch/arm/kernel/entry-common.S +++ b/arch/arm/kernel/entry-common.S | |||
@@ -442,10 +442,10 @@ local_restart: | |||
442 | ldrcc pc, [tbl, scno, lsl #2] @ call sys_* routine | 442 | ldrcc pc, [tbl, scno, lsl #2] @ call sys_* routine |
443 | 443 | ||
444 | add r1, sp, #S_OFF | 444 | add r1, sp, #S_OFF |
445 | 2: mov why, #0 @ no longer a real syscall | ||
446 | cmp scno, #(__ARM_NR_BASE - __NR_SYSCALL_BASE) | 445 | cmp scno, #(__ARM_NR_BASE - __NR_SYSCALL_BASE) |
447 | eor r0, scno, #__NR_SYSCALL_BASE @ put OS number back | 446 | eor r0, scno, #__NR_SYSCALL_BASE @ put OS number back |
448 | bcs arm_syscall | 447 | bcs arm_syscall |
448 | 2: mov why, #0 @ no longer a real syscall | ||
449 | b sys_ni_syscall @ not private func | 449 | b sys_ni_syscall @ not private func |
450 | 450 | ||
451 | #if defined(CONFIG_OABI_COMPAT) || !defined(CONFIG_AEABI) | 451 | #if defined(CONFIG_OABI_COMPAT) || !defined(CONFIG_AEABI) |
diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c index 85c3fb6c93c2..084dc8896986 100644 --- a/arch/arm/kernel/module.c +++ b/arch/arm/kernel/module.c | |||
@@ -292,12 +292,20 @@ int module_finalize(const Elf32_Ehdr *hdr, const Elf_Shdr *sechdrs, | |||
292 | maps[ARM_SEC_CORE].unw_sec = s; | 292 | maps[ARM_SEC_CORE].unw_sec = s; |
293 | else if (strcmp(".ARM.exidx.exit.text", secname) == 0) | 293 | else if (strcmp(".ARM.exidx.exit.text", secname) == 0) |
294 | maps[ARM_SEC_EXIT].unw_sec = s; | 294 | maps[ARM_SEC_EXIT].unw_sec = s; |
295 | else if (strcmp(".ARM.exidx.text.unlikely", secname) == 0) | ||
296 | maps[ARM_SEC_UNLIKELY].unw_sec = s; | ||
297 | else if (strcmp(".ARM.exidx.text.hot", secname) == 0) | ||
298 | maps[ARM_SEC_HOT].unw_sec = s; | ||
295 | else if (strcmp(".init.text", secname) == 0) | 299 | else if (strcmp(".init.text", secname) == 0) |
296 | maps[ARM_SEC_INIT].txt_sec = s; | 300 | maps[ARM_SEC_INIT].txt_sec = s; |
297 | else if (strcmp(".text", secname) == 0) | 301 | else if (strcmp(".text", secname) == 0) |
298 | maps[ARM_SEC_CORE].txt_sec = s; | 302 | maps[ARM_SEC_CORE].txt_sec = s; |
299 | else if (strcmp(".exit.text", secname) == 0) | 303 | else if (strcmp(".exit.text", secname) == 0) |
300 | maps[ARM_SEC_EXIT].txt_sec = s; | 304 | maps[ARM_SEC_EXIT].txt_sec = s; |
305 | else if (strcmp(".text.unlikely", secname) == 0) | ||
306 | maps[ARM_SEC_UNLIKELY].txt_sec = s; | ||
307 | else if (strcmp(".text.hot", secname) == 0) | ||
308 | maps[ARM_SEC_HOT].txt_sec = s; | ||
301 | } | 309 | } |
302 | 310 | ||
303 | for (i = 0; i < ARM_SEC_MAX; i++) | 311 | for (i = 0; i < ARM_SEC_MAX; i++) |
diff --git a/arch/arm/kernel/perf_event_cpu.c b/arch/arm/kernel/perf_event_cpu.c index aebe0e99c153..8d6147b2001f 100644 --- a/arch/arm/kernel/perf_event_cpu.c +++ b/arch/arm/kernel/perf_event_cpu.c | |||
@@ -118,7 +118,8 @@ static int cpu_pmu_request_irq(struct arm_pmu *cpu_pmu, irq_handler_t handler) | |||
118 | continue; | 118 | continue; |
119 | } | 119 | } |
120 | 120 | ||
121 | err = request_irq(irq, handler, IRQF_NOBALANCING, "arm-pmu", | 121 | err = request_irq(irq, handler, |
122 | IRQF_NOBALANCING | IRQF_NO_THREAD, "arm-pmu", | ||
122 | cpu_pmu); | 123 | cpu_pmu); |
123 | if (err) { | 124 | if (err) { |
124 | pr_err("unable to request IRQ%d for ARM PMU counters\n", | 125 | pr_err("unable to request IRQ%d for ARM PMU counters\n", |
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index afc2489ee13b..0e1e2b3afa45 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c | |||
@@ -72,10 +72,10 @@ static int __init fpe_setup(char *line) | |||
72 | __setup("fpe=", fpe_setup); | 72 | __setup("fpe=", fpe_setup); |
73 | #endif | 73 | #endif |
74 | 74 | ||
75 | extern void paging_init(struct machine_desc *desc); | 75 | extern void paging_init(const struct machine_desc *desc); |
76 | extern void sanity_check_meminfo(void); | 76 | extern void sanity_check_meminfo(void); |
77 | extern enum reboot_mode reboot_mode; | 77 | extern enum reboot_mode reboot_mode; |
78 | extern void setup_dma_zone(struct machine_desc *desc); | 78 | extern void setup_dma_zone(const struct machine_desc *desc); |
79 | 79 | ||
80 | unsigned int processor_id; | 80 | unsigned int processor_id; |
81 | EXPORT_SYMBOL(processor_id); | 81 | EXPORT_SYMBOL(processor_id); |
@@ -139,7 +139,7 @@ EXPORT_SYMBOL(elf_platform); | |||
139 | static const char *cpu_name; | 139 | static const char *cpu_name; |
140 | static const char *machine_name; | 140 | static const char *machine_name; |
141 | static char __initdata cmd_line[COMMAND_LINE_SIZE]; | 141 | static char __initdata cmd_line[COMMAND_LINE_SIZE]; |
142 | struct machine_desc *machine_desc __initdata; | 142 | const struct machine_desc *machine_desc __initdata; |
143 | 143 | ||
144 | static union { char c[4]; unsigned long l; } endian_test __initdata = { { 'l', '?', '?', 'b' } }; | 144 | static union { char c[4]; unsigned long l; } endian_test __initdata = { { 'l', '?', '?', 'b' } }; |
145 | #define ENDIANNESS ((char)endian_test.l) | 145 | #define ENDIANNESS ((char)endian_test.l) |
@@ -607,7 +607,7 @@ static void __init setup_processor(void) | |||
607 | 607 | ||
608 | void __init dump_machine_table(void) | 608 | void __init dump_machine_table(void) |
609 | { | 609 | { |
610 | struct machine_desc *p; | 610 | const struct machine_desc *p; |
611 | 611 | ||
612 | early_print("Available machine support:\n\nID (hex)\tNAME\n"); | 612 | early_print("Available machine support:\n\nID (hex)\tNAME\n"); |
613 | for_each_machine_desc(p) | 613 | for_each_machine_desc(p) |
@@ -694,7 +694,7 @@ static int __init early_mem(char *p) | |||
694 | } | 694 | } |
695 | early_param("mem", early_mem); | 695 | early_param("mem", early_mem); |
696 | 696 | ||
697 | static void __init request_standard_resources(struct machine_desc *mdesc) | 697 | static void __init request_standard_resources(const struct machine_desc *mdesc) |
698 | { | 698 | { |
699 | struct memblock_region *region; | 699 | struct memblock_region *region; |
700 | struct resource *res; | 700 | struct resource *res; |
@@ -852,7 +852,7 @@ void __init hyp_mode_check(void) | |||
852 | 852 | ||
853 | void __init setup_arch(char **cmdline_p) | 853 | void __init setup_arch(char **cmdline_p) |
854 | { | 854 | { |
855 | struct machine_desc *mdesc; | 855 | const struct machine_desc *mdesc; |
856 | 856 | ||
857 | setup_processor(); | 857 | setup_processor(); |
858 | mdesc = setup_machine_fdt(__atags_pointer); | 858 | mdesc = setup_machine_fdt(__atags_pointer); |
@@ -994,15 +994,6 @@ static int c_show(struct seq_file *m, void *v) | |||
994 | seq_printf(m, "model name\t: %s rev %d (%s)\n", | 994 | seq_printf(m, "model name\t: %s rev %d (%s)\n", |
995 | cpu_name, cpuid & 15, elf_platform); | 995 | cpu_name, cpuid & 15, elf_platform); |
996 | 996 | ||
997 | #if defined(CONFIG_SMP) | ||
998 | seq_printf(m, "BogoMIPS\t: %lu.%02lu\n", | ||
999 | per_cpu(cpu_data, i).loops_per_jiffy / (500000UL/HZ), | ||
1000 | (per_cpu(cpu_data, i).loops_per_jiffy / (5000UL/HZ)) % 100); | ||
1001 | #else | ||
1002 | seq_printf(m, "BogoMIPS\t: %lu.%02lu\n", | ||
1003 | loops_per_jiffy / (500000/HZ), | ||
1004 | (loops_per_jiffy / (5000/HZ)) % 100); | ||
1005 | #endif | ||
1006 | /* dump out the processor features */ | 997 | /* dump out the processor features */ |
1007 | seq_puts(m, "Features\t: "); | 998 | seq_puts(m, "Features\t: "); |
1008 | 999 | ||
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index 2dc19349eb19..92d10e503746 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c | |||
@@ -398,17 +398,8 @@ asmlinkage void secondary_start_kernel(void) | |||
398 | 398 | ||
399 | void __init smp_cpus_done(unsigned int max_cpus) | 399 | void __init smp_cpus_done(unsigned int max_cpus) |
400 | { | 400 | { |
401 | int cpu; | 401 | printk(KERN_INFO "SMP: Total of %d processors activated.\n", |
402 | unsigned long bogosum = 0; | 402 | num_online_cpus()); |
403 | |||
404 | for_each_online_cpu(cpu) | ||
405 | bogosum += per_cpu(cpu_data, cpu).loops_per_jiffy; | ||
406 | |||
407 | printk(KERN_INFO "SMP: Total of %d processors activated " | ||
408 | "(%lu.%02lu BogoMIPS).\n", | ||
409 | num_online_cpus(), | ||
410 | bogosum / (500000/HZ), | ||
411 | (bogosum / (5000/HZ)) % 100); | ||
412 | 403 | ||
413 | hyp_mode_check(); | 404 | hyp_mode_check(); |
414 | } | 405 | } |
diff --git a/arch/arm/kernel/smp_tlb.c b/arch/arm/kernel/smp_tlb.c index c2edfff573c2..83ccca303df8 100644 --- a/arch/arm/kernel/smp_tlb.c +++ b/arch/arm/kernel/smp_tlb.c | |||
@@ -104,7 +104,7 @@ void flush_tlb_all(void) | |||
104 | if (tlb_ops_need_broadcast()) | 104 | if (tlb_ops_need_broadcast()) |
105 | on_each_cpu(ipi_flush_tlb_all, NULL, 1); | 105 | on_each_cpu(ipi_flush_tlb_all, NULL, 1); |
106 | else | 106 | else |
107 | local_flush_tlb_all(); | 107 | __flush_tlb_all(); |
108 | broadcast_tlb_a15_erratum(); | 108 | broadcast_tlb_a15_erratum(); |
109 | } | 109 | } |
110 | 110 | ||
@@ -113,7 +113,7 @@ void flush_tlb_mm(struct mm_struct *mm) | |||
113 | if (tlb_ops_need_broadcast()) | 113 | if (tlb_ops_need_broadcast()) |
114 | on_each_cpu_mask(mm_cpumask(mm), ipi_flush_tlb_mm, mm, 1); | 114 | on_each_cpu_mask(mm_cpumask(mm), ipi_flush_tlb_mm, mm, 1); |
115 | else | 115 | else |
116 | local_flush_tlb_mm(mm); | 116 | __flush_tlb_mm(mm); |
117 | broadcast_tlb_mm_a15_erratum(mm); | 117 | broadcast_tlb_mm_a15_erratum(mm); |
118 | } | 118 | } |
119 | 119 | ||
@@ -126,7 +126,7 @@ void flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr) | |||
126 | on_each_cpu_mask(mm_cpumask(vma->vm_mm), ipi_flush_tlb_page, | 126 | on_each_cpu_mask(mm_cpumask(vma->vm_mm), ipi_flush_tlb_page, |
127 | &ta, 1); | 127 | &ta, 1); |
128 | } else | 128 | } else |
129 | local_flush_tlb_page(vma, uaddr); | 129 | __flush_tlb_page(vma, uaddr); |
130 | broadcast_tlb_mm_a15_erratum(vma->vm_mm); | 130 | broadcast_tlb_mm_a15_erratum(vma->vm_mm); |
131 | } | 131 | } |
132 | 132 | ||
@@ -137,7 +137,7 @@ void flush_tlb_kernel_page(unsigned long kaddr) | |||
137 | ta.ta_start = kaddr; | 137 | ta.ta_start = kaddr; |
138 | on_each_cpu(ipi_flush_tlb_kernel_page, &ta, 1); | 138 | on_each_cpu(ipi_flush_tlb_kernel_page, &ta, 1); |
139 | } else | 139 | } else |
140 | local_flush_tlb_kernel_page(kaddr); | 140 | __flush_tlb_kernel_page(kaddr); |
141 | broadcast_tlb_a15_erratum(); | 141 | broadcast_tlb_a15_erratum(); |
142 | } | 142 | } |
143 | 143 | ||
@@ -173,5 +173,5 @@ void flush_bp_all(void) | |||
173 | if (tlb_ops_need_broadcast()) | 173 | if (tlb_ops_need_broadcast()) |
174 | on_each_cpu(ipi_flush_bp_all, NULL, 1); | 174 | on_each_cpu(ipi_flush_bp_all, NULL, 1); |
175 | else | 175 | else |
176 | local_flush_bp_all(); | 176 | __flush_bp_all(); |
177 | } | 177 | } |
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index ab517fcce21b..8fcda140358d 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c | |||
@@ -497,28 +497,64 @@ static int bad_syscall(int n, struct pt_regs *regs) | |||
497 | return regs->ARM_r0; | 497 | return regs->ARM_r0; |
498 | } | 498 | } |
499 | 499 | ||
500 | static long do_cache_op_restart(struct restart_block *); | ||
501 | |||
500 | static inline int | 502 | static inline int |
501 | do_cache_op(unsigned long start, unsigned long end, int flags) | 503 | __do_cache_op(unsigned long start, unsigned long end) |
502 | { | 504 | { |
503 | struct mm_struct *mm = current->active_mm; | 505 | int ret; |
504 | struct vm_area_struct *vma; | 506 | unsigned long chunk = PAGE_SIZE; |
507 | |||
508 | do { | ||
509 | if (signal_pending(current)) { | ||
510 | struct thread_info *ti = current_thread_info(); | ||
511 | |||
512 | ti->restart_block = (struct restart_block) { | ||
513 | .fn = do_cache_op_restart, | ||
514 | }; | ||
515 | |||
516 | ti->arm_restart_block = (struct arm_restart_block) { | ||
517 | { | ||
518 | .cache = { | ||
519 | .start = start, | ||
520 | .end = end, | ||
521 | }, | ||
522 | }, | ||
523 | }; | ||
524 | |||
525 | return -ERESTART_RESTARTBLOCK; | ||
526 | } | ||
527 | |||
528 | ret = flush_cache_user_range(start, start + chunk); | ||
529 | if (ret) | ||
530 | return ret; | ||
505 | 531 | ||
532 | cond_resched(); | ||
533 | start += chunk; | ||
534 | } while (start < end); | ||
535 | |||
536 | return 0; | ||
537 | } | ||
538 | |||
539 | static long do_cache_op_restart(struct restart_block *unused) | ||
540 | { | ||
541 | struct arm_restart_block *restart_block; | ||
542 | |||
543 | restart_block = ¤t_thread_info()->arm_restart_block; | ||
544 | return __do_cache_op(restart_block->cache.start, | ||
545 | restart_block->cache.end); | ||
546 | } | ||
547 | |||
548 | static inline int | ||
549 | do_cache_op(unsigned long start, unsigned long end, int flags) | ||
550 | { | ||
506 | if (end < start || flags) | 551 | if (end < start || flags) |
507 | return -EINVAL; | 552 | return -EINVAL; |
508 | 553 | ||
509 | down_read(&mm->mmap_sem); | 554 | if (!access_ok(VERIFY_READ, start, end - start)) |
510 | vma = find_vma(mm, start); | 555 | return -EFAULT; |
511 | if (vma && vma->vm_start < end) { | ||
512 | if (start < vma->vm_start) | ||
513 | start = vma->vm_start; | ||
514 | if (end > vma->vm_end) | ||
515 | end = vma->vm_end; | ||
516 | 556 | ||
517 | up_read(&mm->mmap_sem); | 557 | return __do_cache_op(start, end); |
518 | return flush_cache_user_range(start, end); | ||
519 | } | ||
520 | up_read(&mm->mmap_sem); | ||
521 | return -EINVAL; | ||
522 | } | 558 | } |
523 | 559 | ||
524 | /* | 560 | /* |
diff --git a/arch/arm/kernel/v7m.c b/arch/arm/kernel/v7m.c new file mode 100644 index 000000000000..4d2cba94f5cc --- /dev/null +++ b/arch/arm/kernel/v7m.c | |||
@@ -0,0 +1,19 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2013 Uwe Kleine-Koenig for Pengutronix | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it under | ||
5 | * the terms of the GNU General Public License version 2 as published by the | ||
6 | * Free Software Foundation. | ||
7 | */ | ||
8 | #include <linux/io.h> | ||
9 | #include <linux/reboot.h> | ||
10 | #include <asm/barrier.h> | ||
11 | #include <asm/v7m.h> | ||
12 | |||
13 | void armv7m_restart(enum reboot_mode mode, const char *cmd) | ||
14 | { | ||
15 | dsb(); | ||
16 | __raw_writel(V7M_SCB_AIRCR_VECTKEY | V7M_SCB_AIRCR_SYSRESETREQ, | ||
17 | BASEADDR_V7M_SCB + V7M_SCB_AIRCR); | ||
18 | dsb(); | ||
19 | } | ||