aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/kernel')
-rw-r--r--arch/arm/kernel/Makefile3
-rw-r--r--arch/arm/kernel/arch_timer.c350
-rw-r--r--arch/arm/kernel/bios32.c37
-rw-r--r--arch/arm/kernel/entry-armv.S4
-rw-r--r--arch/arm/kernel/entry-common.S28
-rw-r--r--arch/arm/kernel/head.S9
-rw-r--r--arch/arm/kernel/init_task.c37
-rw-r--r--arch/arm/kernel/process.c20
-rw-r--r--arch/arm/kernel/ptrace.c10
-rw-r--r--arch/arm/kernel/signal.c2
-rw-r--r--arch/arm/kernel/smp.c29
-rw-r--r--arch/arm/kernel/smp_scu.c3
-rw-r--r--arch/arm/kernel/thumbee.c4
-rw-r--r--arch/arm/kernel/time.c36
-rw-r--r--arch/arm/kernel/traps.c11
15 files changed, 438 insertions, 145 deletions
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index 7b787d642af4..7ad2d5cf7008 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -34,6 +34,7 @@ obj-$(CONFIG_ARM_CPU_SUSPEND) += sleep.o suspend.o
34obj-$(CONFIG_SMP) += smp.o smp_tlb.o 34obj-$(CONFIG_SMP) += smp.o smp_tlb.o
35obj-$(CONFIG_HAVE_ARM_SCU) += smp_scu.o 35obj-$(CONFIG_HAVE_ARM_SCU) += smp_scu.o
36obj-$(CONFIG_HAVE_ARM_TWD) += smp_twd.o 36obj-$(CONFIG_HAVE_ARM_TWD) += smp_twd.o
37obj-$(CONFIG_ARM_ARCH_TIMER) += arch_timer.o
37obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o insn.o 38obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o insn.o
38obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o insn.o 39obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o insn.o
39obj-$(CONFIG_JUMP_LABEL) += jump_label.o insn.o patch.o 40obj-$(CONFIG_JUMP_LABEL) += jump_label.o insn.o patch.o
@@ -81,4 +82,4 @@ head-y := head$(MMUEXT).o
81obj-$(CONFIG_DEBUG_LL) += debug.o 82obj-$(CONFIG_DEBUG_LL) += debug.o
82obj-$(CONFIG_EARLY_PRINTK) += early_printk.o 83obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
83 84
84extra-y := $(head-y) init_task.o vmlinux.lds 85extra-y := $(head-y) vmlinux.lds
diff --git a/arch/arm/kernel/arch_timer.c b/arch/arm/kernel/arch_timer.c
new file mode 100644
index 000000000000..dd58035621f7
--- /dev/null
+++ b/arch/arm/kernel/arch_timer.c
@@ -0,0 +1,350 @@
1/*
2 * linux/arch/arm/kernel/arch_timer.c
3 *
4 * Copyright (C) 2011 ARM Ltd.
5 * All Rights Reserved
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#include <linux/init.h>
12#include <linux/kernel.h>
13#include <linux/delay.h>
14#include <linux/device.h>
15#include <linux/smp.h>
16#include <linux/cpu.h>
17#include <linux/jiffies.h>
18#include <linux/clockchips.h>
19#include <linux/interrupt.h>
20#include <linux/of_irq.h>
21#include <linux/io.h>
22
23#include <asm/cputype.h>
24#include <asm/localtimer.h>
25#include <asm/arch_timer.h>
26#include <asm/system_info.h>
27#include <asm/sched_clock.h>
28
29static unsigned long arch_timer_rate;
30static int arch_timer_ppi;
31static int arch_timer_ppi2;
32
33static struct clock_event_device __percpu **arch_timer_evt;
34
35/*
36 * Architected system timer support.
37 */
38
39#define ARCH_TIMER_CTRL_ENABLE (1 << 0)
40#define ARCH_TIMER_CTRL_IT_MASK (1 << 1)
41#define ARCH_TIMER_CTRL_IT_STAT (1 << 2)
42
43#define ARCH_TIMER_REG_CTRL 0
44#define ARCH_TIMER_REG_FREQ 1
45#define ARCH_TIMER_REG_TVAL 2
46
47static void arch_timer_reg_write(int reg, u32 val)
48{
49 switch (reg) {
50 case ARCH_TIMER_REG_CTRL:
51 asm volatile("mcr p15, 0, %0, c14, c2, 1" : : "r" (val));
52 break;
53 case ARCH_TIMER_REG_TVAL:
54 asm volatile("mcr p15, 0, %0, c14, c2, 0" : : "r" (val));
55 break;
56 }
57
58 isb();
59}
60
61static u32 arch_timer_reg_read(int reg)
62{
63 u32 val;
64
65 switch (reg) {
66 case ARCH_TIMER_REG_CTRL:
67 asm volatile("mrc p15, 0, %0, c14, c2, 1" : "=r" (val));
68 break;
69 case ARCH_TIMER_REG_FREQ:
70 asm volatile("mrc p15, 0, %0, c14, c0, 0" : "=r" (val));
71 break;
72 case ARCH_TIMER_REG_TVAL:
73 asm volatile("mrc p15, 0, %0, c14, c2, 0" : "=r" (val));
74 break;
75 default:
76 BUG();
77 }
78
79 return val;
80}
81
82static irqreturn_t arch_timer_handler(int irq, void *dev_id)
83{
84 struct clock_event_device *evt = *(struct clock_event_device **)dev_id;
85 unsigned long ctrl;
86
87 ctrl = arch_timer_reg_read(ARCH_TIMER_REG_CTRL);
88 if (ctrl & ARCH_TIMER_CTRL_IT_STAT) {
89 ctrl |= ARCH_TIMER_CTRL_IT_MASK;
90 arch_timer_reg_write(ARCH_TIMER_REG_CTRL, ctrl);
91 evt->event_handler(evt);
92 return IRQ_HANDLED;
93 }
94
95 return IRQ_NONE;
96}
97
98static void arch_timer_disable(void)
99{
100 unsigned long ctrl;
101
102 ctrl = arch_timer_reg_read(ARCH_TIMER_REG_CTRL);
103 ctrl &= ~ARCH_TIMER_CTRL_ENABLE;
104 arch_timer_reg_write(ARCH_TIMER_REG_CTRL, ctrl);
105}
106
107static void arch_timer_set_mode(enum clock_event_mode mode,
108 struct clock_event_device *clk)
109{
110 switch (mode) {
111 case CLOCK_EVT_MODE_UNUSED:
112 case CLOCK_EVT_MODE_SHUTDOWN:
113 arch_timer_disable();
114 break;
115 default:
116 break;
117 }
118}
119
120static int arch_timer_set_next_event(unsigned long evt,
121 struct clock_event_device *unused)
122{
123 unsigned long ctrl;
124
125 ctrl = arch_timer_reg_read(ARCH_TIMER_REG_CTRL);
126 ctrl |= ARCH_TIMER_CTRL_ENABLE;
127 ctrl &= ~ARCH_TIMER_CTRL_IT_MASK;
128
129 arch_timer_reg_write(ARCH_TIMER_REG_TVAL, evt);
130 arch_timer_reg_write(ARCH_TIMER_REG_CTRL, ctrl);
131
132 return 0;
133}
134
135static int __cpuinit arch_timer_setup(struct clock_event_device *clk)
136{
137 /* Be safe... */
138 arch_timer_disable();
139
140 clk->features = CLOCK_EVT_FEAT_ONESHOT;
141 clk->name = "arch_sys_timer";
142 clk->rating = 450;
143 clk->set_mode = arch_timer_set_mode;
144 clk->set_next_event = arch_timer_set_next_event;
145 clk->irq = arch_timer_ppi;
146
147 clockevents_config_and_register(clk, arch_timer_rate,
148 0xf, 0x7fffffff);
149
150 *__this_cpu_ptr(arch_timer_evt) = clk;
151
152 enable_percpu_irq(clk->irq, 0);
153 if (arch_timer_ppi2)
154 enable_percpu_irq(arch_timer_ppi2, 0);
155
156 return 0;
157}
158
159/* Is the optional system timer available? */
160static int local_timer_is_architected(void)
161{
162 return (cpu_architecture() >= CPU_ARCH_ARMv7) &&
163 ((read_cpuid_ext(CPUID_EXT_PFR1) >> 16) & 0xf) == 1;
164}
165
166static int arch_timer_available(void)
167{
168 unsigned long freq;
169
170 if (!local_timer_is_architected())
171 return -ENXIO;
172
173 if (arch_timer_rate == 0) {
174 arch_timer_reg_write(ARCH_TIMER_REG_CTRL, 0);
175 freq = arch_timer_reg_read(ARCH_TIMER_REG_FREQ);
176
177 /* Check the timer frequency. */
178 if (freq == 0) {
179 pr_warn("Architected timer frequency not available\n");
180 return -EINVAL;
181 }
182
183 arch_timer_rate = freq;
184 }
185
186 pr_info_once("Architected local timer running at %lu.%02luMHz.\n",
187 arch_timer_rate / 1000000, (arch_timer_rate / 10000) % 100);
188 return 0;
189}
190
191static inline cycle_t arch_counter_get_cntpct(void)
192{
193 u32 cvall, cvalh;
194
195 asm volatile("mrrc p15, 0, %0, %1, c14" : "=r" (cvall), "=r" (cvalh));
196
197 return ((cycle_t) cvalh << 32) | cvall;
198}
199
200static inline cycle_t arch_counter_get_cntvct(void)
201{
202 u32 cvall, cvalh;
203
204 asm volatile("mrrc p15, 1, %0, %1, c14" : "=r" (cvall), "=r" (cvalh));
205
206 return ((cycle_t) cvalh << 32) | cvall;
207}
208
209static u32 notrace arch_counter_get_cntvct32(void)
210{
211 cycle_t cntvct = arch_counter_get_cntvct();
212
213 /*
214 * The sched_clock infrastructure only knows about counters
215 * with at most 32bits. Forget about the upper 24 bits for the
216 * time being...
217 */
218 return (u32)(cntvct & (u32)~0);
219}
220
221static cycle_t arch_counter_read(struct clocksource *cs)
222{
223 return arch_counter_get_cntpct();
224}
225
226static struct clocksource clocksource_counter = {
227 .name = "arch_sys_counter",
228 .rating = 400,
229 .read = arch_counter_read,
230 .mask = CLOCKSOURCE_MASK(56),
231 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
232};
233
234static void __cpuinit arch_timer_stop(struct clock_event_device *clk)
235{
236 pr_debug("arch_timer_teardown disable IRQ%d cpu #%d\n",
237 clk->irq, smp_processor_id());
238 disable_percpu_irq(clk->irq);
239 if (arch_timer_ppi2)
240 disable_percpu_irq(arch_timer_ppi2);
241 arch_timer_set_mode(CLOCK_EVT_MODE_UNUSED, clk);
242}
243
244static struct local_timer_ops arch_timer_ops __cpuinitdata = {
245 .setup = arch_timer_setup,
246 .stop = arch_timer_stop,
247};
248
249static struct clock_event_device arch_timer_global_evt;
250
251static int __init arch_timer_register(void)
252{
253 int err;
254
255 err = arch_timer_available();
256 if (err)
257 return err;
258
259 arch_timer_evt = alloc_percpu(struct clock_event_device *);
260 if (!arch_timer_evt)
261 return -ENOMEM;
262
263 clocksource_register_hz(&clocksource_counter, arch_timer_rate);
264
265 err = request_percpu_irq(arch_timer_ppi, arch_timer_handler,
266 "arch_timer", arch_timer_evt);
267 if (err) {
268 pr_err("arch_timer: can't register interrupt %d (%d)\n",
269 arch_timer_ppi, err);
270 goto out_free;
271 }
272
273 if (arch_timer_ppi2) {
274 err = request_percpu_irq(arch_timer_ppi2, arch_timer_handler,
275 "arch_timer", arch_timer_evt);
276 if (err) {
277 pr_err("arch_timer: can't register interrupt %d (%d)\n",
278 arch_timer_ppi2, err);
279 arch_timer_ppi2 = 0;
280 goto out_free_irq;
281 }
282 }
283
284 err = local_timer_register(&arch_timer_ops);
285 if (err) {
286 /*
287 * We couldn't register as a local timer (could be
288 * because we're on a UP platform, or because some
289 * other local timer is already present...). Try as a
290 * global timer instead.
291 */
292 arch_timer_global_evt.cpumask = cpumask_of(0);
293 err = arch_timer_setup(&arch_timer_global_evt);
294 }
295
296 if (err)
297 goto out_free_irq;
298
299 return 0;
300
301out_free_irq:
302 free_percpu_irq(arch_timer_ppi, arch_timer_evt);
303 if (arch_timer_ppi2)
304 free_percpu_irq(arch_timer_ppi2, arch_timer_evt);
305
306out_free:
307 free_percpu(arch_timer_evt);
308
309 return err;
310}
311
312static const struct of_device_id arch_timer_of_match[] __initconst = {
313 { .compatible = "arm,armv7-timer", },
314 {},
315};
316
317int __init arch_timer_of_register(void)
318{
319 struct device_node *np;
320 u32 freq;
321
322 np = of_find_matching_node(NULL, arch_timer_of_match);
323 if (!np) {
324 pr_err("arch_timer: can't find DT node\n");
325 return -ENODEV;
326 }
327
328 /* Try to determine the frequency from the device tree or CNTFRQ */
329 if (!of_property_read_u32(np, "clock-frequency", &freq))
330 arch_timer_rate = freq;
331
332 arch_timer_ppi = irq_of_parse_and_map(np, 0);
333 arch_timer_ppi2 = irq_of_parse_and_map(np, 1);
334 pr_info("arch_timer: found %s irqs %d %d\n",
335 np->name, arch_timer_ppi, arch_timer_ppi2);
336
337 return arch_timer_register();
338}
339
340int __init arch_timer_sched_clock_init(void)
341{
342 int err;
343
344 err = arch_timer_available();
345 if (err)
346 return err;
347
348 setup_sched_clock(arch_counter_get_cntvct32, 32, arch_timer_rate);
349 return 0;
350}
diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
index ede5f7741c42..25552508c3fd 100644
--- a/arch/arm/kernel/bios32.c
+++ b/arch/arm/kernel/bios32.c
@@ -374,16 +374,29 @@ EXPORT_SYMBOL(pcibios_fixup_bus);
374#endif 374#endif
375 375
376/* 376/*
377 * Swizzle the device pin each time we cross a bridge. 377 * Swizzle the device pin each time we cross a bridge. If a platform does
378 * This might update pin and returns the slot number. 378 * not provide a swizzle function, we perform the standard PCI swizzling.
379 *
380 * The default swizzling walks up the bus tree one level at a time, applying
381 * the standard swizzle function at each step, stopping when it finds the PCI
382 * root bus. This will return the slot number of the bridge device on the
383 * root bus and the interrupt pin on that device which should correspond
384 * with the downstream device interrupt.
385 *
386 * Platforms may override this, in which case the slot and pin returned
387 * depend entirely on the platform code. However, please note that the
388 * PCI standard swizzle is implemented on plug-in cards and Cardbus based
389 * PCI extenders, so it can not be ignored.
379 */ 390 */
380static u8 __devinit pcibios_swizzle(struct pci_dev *dev, u8 *pin) 391static u8 __devinit pcibios_swizzle(struct pci_dev *dev, u8 *pin)
381{ 392{
382 struct pci_sys_data *sys = dev->sysdata; 393 struct pci_sys_data *sys = dev->sysdata;
383 int slot = 0, oldpin = *pin; 394 int slot, oldpin = *pin;
384 395
385 if (sys->swizzle) 396 if (sys->swizzle)
386 slot = sys->swizzle(dev, pin); 397 slot = sys->swizzle(dev, pin);
398 else
399 slot = pci_common_swizzle(dev, pin);
387 400
388 if (debug_pci) 401 if (debug_pci)
389 printk("PCI: %s swizzling pin %d => pin %d slot %d\n", 402 printk("PCI: %s swizzling pin %d => pin %d slot %d\n",
@@ -410,7 +423,7 @@ static int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
410 return irq; 423 return irq;
411} 424}
412 425
413static void __init pcibios_init_hw(struct hw_pci *hw) 426static void __init pcibios_init_hw(struct hw_pci *hw, struct list_head *head)
414{ 427{
415 struct pci_sys_data *sys = NULL; 428 struct pci_sys_data *sys = NULL;
416 int ret; 429 int ret;
@@ -424,7 +437,6 @@ static void __init pcibios_init_hw(struct hw_pci *hw)
424#ifdef CONFIG_PCI_DOMAINS 437#ifdef CONFIG_PCI_DOMAINS
425 sys->domain = hw->domain; 438 sys->domain = hw->domain;
426#endif 439#endif
427 sys->hw = hw;
428 sys->busnr = busnr; 440 sys->busnr = busnr;
429 sys->swizzle = hw->swizzle; 441 sys->swizzle = hw->swizzle;
430 sys->map_irq = hw->map_irq; 442 sys->map_irq = hw->map_irq;
@@ -440,14 +452,18 @@ static void __init pcibios_init_hw(struct hw_pci *hw)
440 &iomem_resource, sys->mem_offset); 452 &iomem_resource, sys->mem_offset);
441 } 453 }
442 454
443 sys->bus = hw->scan(nr, sys); 455 if (hw->scan)
456 sys->bus = hw->scan(nr, sys);
457 else
458 sys->bus = pci_scan_root_bus(NULL, sys->busnr,
459 hw->ops, sys, &sys->resources);
444 460
445 if (!sys->bus) 461 if (!sys->bus)
446 panic("PCI: unable to scan bus!"); 462 panic("PCI: unable to scan bus!");
447 463
448 busnr = sys->bus->subordinate + 1; 464 busnr = sys->bus->subordinate + 1;
449 465
450 list_add(&sys->node, &hw->buses); 466 list_add(&sys->node, head);
451 } else { 467 } else {
452 kfree(sys); 468 kfree(sys);
453 if (ret < 0) 469 if (ret < 0)
@@ -459,19 +475,18 @@ static void __init pcibios_init_hw(struct hw_pci *hw)
459void __init pci_common_init(struct hw_pci *hw) 475void __init pci_common_init(struct hw_pci *hw)
460{ 476{
461 struct pci_sys_data *sys; 477 struct pci_sys_data *sys;
462 478 LIST_HEAD(head);
463 INIT_LIST_HEAD(&hw->buses);
464 479
465 pci_add_flags(PCI_REASSIGN_ALL_RSRC); 480 pci_add_flags(PCI_REASSIGN_ALL_RSRC);
466 if (hw->preinit) 481 if (hw->preinit)
467 hw->preinit(); 482 hw->preinit();
468 pcibios_init_hw(hw); 483 pcibios_init_hw(hw, &head);
469 if (hw->postinit) 484 if (hw->postinit)
470 hw->postinit(); 485 hw->postinit();
471 486
472 pci_fixup_irqs(pcibios_swizzle, pcibios_map_irq); 487 pci_fixup_irqs(pcibios_swizzle, pcibios_map_irq);
473 488
474 list_for_each_entry(sys, &hw->buses, node) { 489 list_for_each_entry(sys, &head, node) {
475 struct pci_bus *bus = sys->bus; 490 struct pci_bus *bus = sys->bus;
476 491
477 if (!pci_has_flag(PCI_PROBE_ONLY)) { 492 if (!pci_has_flag(PCI_PROBE_ONLY)) {
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 7fd3ad048da9..437f0c426517 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -556,10 +556,6 @@ call_fpe:
556#endif 556#endif
557 tst r0, #0x08000000 @ only CDP/CPRT/LDC/STC have bit 27 557 tst r0, #0x08000000 @ only CDP/CPRT/LDC/STC have bit 27
558 tstne r0, #0x04000000 @ bit 26 set on both ARM and Thumb-2 558 tstne r0, #0x04000000 @ bit 26 set on both ARM and Thumb-2
559#if defined(CONFIG_CPU_ARM610) || defined(CONFIG_CPU_ARM710)
560 and r8, r0, #0x0f000000 @ mask out op-code bits
561 teqne r8, #0x0f000000 @ SWI (ARM6/7 bug)?
562#endif
563 moveq pc, lr 559 moveq pc, lr
564 get_thread_info r10 @ get current thread 560 get_thread_info r10 @ get current thread
565 and r8, r0, #0x00000f00 @ mask out CP number 561 and r8, r0, #0x00000f00 @ mask out CP number
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index b669b49d7cc4..4afed88d250a 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -339,20 +339,6 @@ ENDPROC(ftrace_stub)
339 *----------------------------------------------------------------------------- 339 *-----------------------------------------------------------------------------
340 */ 340 */
341 341
342 /* If we're optimising for StrongARM the resulting code won't
343 run on an ARM7 and we can save a couple of instructions.
344 --pb */
345#ifdef CONFIG_CPU_ARM710
346#define A710(code...) code
347.Larm710bug:
348 ldmia sp, {r0 - lr}^ @ Get calling r0 - lr
349 mov r0, r0
350 add sp, sp, #S_FRAME_SIZE
351 subs pc, lr, #4
352#else
353#define A710(code...)
354#endif
355
356 .align 5 342 .align 5
357ENTRY(vector_swi) 343ENTRY(vector_swi)
358 sub sp, sp, #S_FRAME_SIZE 344 sub sp, sp, #S_FRAME_SIZE
@@ -383,9 +369,6 @@ ENTRY(vector_swi)
383 ldreq r10, [lr, #-4] @ get SWI instruction 369 ldreq r10, [lr, #-4] @ get SWI instruction
384#else 370#else
385 ldr r10, [lr, #-4] @ get SWI instruction 371 ldr r10, [lr, #-4] @ get SWI instruction
386 A710( and ip, r10, #0x0f000000 @ check for SWI )
387 A710( teq ip, #0x0f000000 )
388 A710( bne .Larm710bug )
389#endif 372#endif
390#ifdef CONFIG_CPU_ENDIAN_BE8 373#ifdef CONFIG_CPU_ENDIAN_BE8
391 rev r10, r10 @ little endian instruction 374 rev r10, r10 @ little endian instruction
@@ -396,26 +379,15 @@ ENTRY(vector_swi)
396 /* 379 /*
397 * Pure EABI user space always put syscall number into scno (r7). 380 * Pure EABI user space always put syscall number into scno (r7).
398 */ 381 */
399 A710( ldr ip, [lr, #-4] @ get SWI instruction )
400 A710( and ip, ip, #0x0f000000 @ check for SWI )
401 A710( teq ip, #0x0f000000 )
402 A710( bne .Larm710bug )
403
404#elif defined(CONFIG_ARM_THUMB) 382#elif defined(CONFIG_ARM_THUMB)
405
406 /* Legacy ABI only, possibly thumb mode. */ 383 /* Legacy ABI only, possibly thumb mode. */
407 tst r8, #PSR_T_BIT @ this is SPSR from save_user_regs 384 tst r8, #PSR_T_BIT @ this is SPSR from save_user_regs
408 addne scno, r7, #__NR_SYSCALL_BASE @ put OS number in 385 addne scno, r7, #__NR_SYSCALL_BASE @ put OS number in
409 ldreq scno, [lr, #-4] 386 ldreq scno, [lr, #-4]
410 387
411#else 388#else
412
413 /* Legacy ABI only. */ 389 /* Legacy ABI only. */
414 ldr scno, [lr, #-4] @ get SWI instruction 390 ldr scno, [lr, #-4] @ get SWI instruction
415 A710( and ip, scno, #0x0f000000 @ check for SWI )
416 A710( teq ip, #0x0f000000 )
417 A710( bne .Larm710bug )
418
419#endif 391#endif
420 392
421#ifdef CONFIG_ALIGNMENT_TRAP 393#ifdef CONFIG_ALIGNMENT_TRAP
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index 3bf0c7f8b043..835898e7d704 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -277,10 +277,6 @@ __create_page_tables:
277 mov r3, r3, lsl #PMD_ORDER 277 mov r3, r3, lsl #PMD_ORDER
278 278
279 add r0, r4, r3 279 add r0, r4, r3
280 rsb r3, r3, #0x4000 @ PTRS_PER_PGD*sizeof(long)
281 cmp r3, #0x0800 @ limit to 512MB
282 movhi r3, #0x0800
283 add r6, r0, r3
284 mov r3, r7, lsr #SECTION_SHIFT 280 mov r3, r7, lsr #SECTION_SHIFT
285 ldr r7, [r10, #PROCINFO_IO_MMUFLAGS] @ io_mmuflags 281 ldr r7, [r10, #PROCINFO_IO_MMUFLAGS] @ io_mmuflags
286 orr r3, r7, r3, lsl #SECTION_SHIFT 282 orr r3, r7, r3, lsl #SECTION_SHIFT
@@ -289,13 +285,10 @@ __create_page_tables:
289#else 285#else
290 orr r3, r3, #PMD_SECT_XN 286 orr r3, r3, #PMD_SECT_XN
291#endif 287#endif
2921: str r3, [r0], #4 288 str r3, [r0], #4
293#ifdef CONFIG_ARM_LPAE 289#ifdef CONFIG_ARM_LPAE
294 str r7, [r0], #4 290 str r7, [r0], #4
295#endif 291#endif
296 add r3, r3, #1 << SECTION_SHIFT
297 cmp r0, r6
298 blo 1b
299 292
300#else /* CONFIG_DEBUG_ICEDCC || CONFIG_DEBUG_SEMIHOSTING */ 293#else /* CONFIG_DEBUG_ICEDCC || CONFIG_DEBUG_SEMIHOSTING */
301 /* we don't need any serial debugging mappings */ 294 /* we don't need any serial debugging mappings */
diff --git a/arch/arm/kernel/init_task.c b/arch/arm/kernel/init_task.c
deleted file mode 100644
index e7cbb50dc356..000000000000
--- a/arch/arm/kernel/init_task.c
+++ /dev/null
@@ -1,37 +0,0 @@
1/*
2 * linux/arch/arm/kernel/init_task.c
3 */
4#include <linux/mm.h>
5#include <linux/module.h>
6#include <linux/fs.h>
7#include <linux/sched.h>
8#include <linux/init.h>
9#include <linux/init_task.h>
10#include <linux/mqueue.h>
11#include <linux/uaccess.h>
12
13#include <asm/pgtable.h>
14
15static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
16static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
17/*
18 * Initial thread structure.
19 *
20 * We need to make sure that this is 8192-byte aligned due to the
21 * way process stacks are handled. This is done by making sure
22 * the linker maps this in the .text segment right after head.S,
23 * and making head.S ensure the proper alignment.
24 *
25 * The things we do for performance..
26 */
27union thread_union init_thread_union __init_task_data =
28 { INIT_THREAD_INFO(init_task) };
29
30/*
31 * Initial task structure.
32 *
33 * All other task structs will be allocated on slabs in fork.c
34 */
35struct task_struct init_task = INIT_TASK(init_task);
36
37EXPORT_SYMBOL(init_task);
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 2b7b017a20cd..19c95ea65b2f 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -157,26 +157,6 @@ EXPORT_SYMBOL(pm_power_off);
157void (*arm_pm_restart)(char str, const char *cmd) = null_restart; 157void (*arm_pm_restart)(char str, const char *cmd) = null_restart;
158EXPORT_SYMBOL_GPL(arm_pm_restart); 158EXPORT_SYMBOL_GPL(arm_pm_restart);
159 159
160static void do_nothing(void *unused)
161{
162}
163
164/*
165 * cpu_idle_wait - Used to ensure that all the CPUs discard old value of
166 * pm_idle and update to new pm_idle value. Required while changing pm_idle
167 * handler on SMP systems.
168 *
169 * Caller must have changed pm_idle to the new value before the call. Old
170 * pm_idle value will not be used by any CPU after the return of this function.
171 */
172void cpu_idle_wait(void)
173{
174 smp_mb();
175 /* kick all the CPUs so that they exit out of pm_idle */
176 smp_call_function(do_nothing, NULL, 1);
177}
178EXPORT_SYMBOL_GPL(cpu_idle_wait);
179
180/* 160/*
181 * This is our default idle handler. 161 * This is our default idle handler.
182 */ 162 */
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
index 688a0a970c71..5700a7ae7f0b 100644
--- a/arch/arm/kernel/ptrace.c
+++ b/arch/arm/kernel/ptrace.c
@@ -24,6 +24,7 @@
24#include <linux/hw_breakpoint.h> 24#include <linux/hw_breakpoint.h>
25#include <linux/regset.h> 25#include <linux/regset.h>
26#include <linux/audit.h> 26#include <linux/audit.h>
27#include <linux/tracehook.h>
27#include <linux/unistd.h> 28#include <linux/unistd.h>
28 29
29#include <asm/pgtable.h> 30#include <asm/pgtable.h>
@@ -921,8 +922,6 @@ asmlinkage int syscall_trace(int why, struct pt_regs *regs, int scno)
921 scno = __NR_restart_syscall - __NR_SYSCALL_BASE; 922 scno = __NR_restart_syscall - __NR_SYSCALL_BASE;
922 if (!test_thread_flag(TIF_SYSCALL_TRACE)) 923 if (!test_thread_flag(TIF_SYSCALL_TRACE))
923 return scno; 924 return scno;
924 if (!(current->ptrace & PT_PTRACED))
925 return scno;
926 925
927 current_thread_info()->syscall = scno; 926 current_thread_info()->syscall = scno;
928 927
@@ -932,7 +931,12 @@ asmlinkage int syscall_trace(int why, struct pt_regs *regs, int scno)
932 */ 931 */
933 ip = regs->ARM_ip; 932 ip = regs->ARM_ip;
934 regs->ARM_ip = why; 933 regs->ARM_ip = why;
935 ptrace_report_syscall(regs); 934
935 if (why)
936 tracehook_report_syscall_exit(regs, 0);
937 else if (tracehook_report_syscall_entry(regs))
938 current_thread_info()->syscall = -1;
939
936 regs->ARM_ip = ip; 940 regs->ARM_ip = ip;
937 941
938 return current_thread_info()->syscall; 942 return current_thread_info()->syscall;
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index 869c4988fefc..b7ffda1ad8f2 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -576,6 +576,8 @@ handle_signal(unsigned long sig, struct k_sigaction *ka,
576 */ 576 */
577 block_sigmask(ka, sig); 577 block_sigmask(ka, sig);
578 578
579 tracehook_signal_handler(sig, info, ka, regs, 0);
580
579 return 0; 581 return 0;
580} 582}
581 583
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 8f4644659777..b735521a4a54 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -60,32 +60,11 @@ enum ipi_msg_type {
60 60
61static DECLARE_COMPLETION(cpu_running); 61static DECLARE_COMPLETION(cpu_running);
62 62
63int __cpuinit __cpu_up(unsigned int cpu) 63int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *idle)
64{ 64{
65 struct cpuinfo_arm *ci = &per_cpu(cpu_data, cpu);
66 struct task_struct *idle = ci->idle;
67 int ret; 65 int ret;
68 66
69 /* 67 /*
70 * Spawn a new process manually, if not already done.
71 * Grab a pointer to its task struct so we can mess with it
72 */
73 if (!idle) {
74 idle = fork_idle(cpu);
75 if (IS_ERR(idle)) {
76 printk(KERN_ERR "CPU%u: fork() failed\n", cpu);
77 return PTR_ERR(idle);
78 }
79 ci->idle = idle;
80 } else {
81 /*
82 * Since this idle thread is being re-used, call
83 * init_idle() to reinitialize the thread structure.
84 */
85 init_idle(idle, cpu);
86 }
87
88 /*
89 * We need to tell the secondary core where to find 68 * We need to tell the secondary core where to find
90 * its stack and the page tables. 69 * its stack and the page tables.
91 */ 70 */
@@ -318,9 +297,6 @@ void __init smp_cpus_done(unsigned int max_cpus)
318 297
319void __init smp_prepare_boot_cpu(void) 298void __init smp_prepare_boot_cpu(void)
320{ 299{
321 unsigned int cpu = smp_processor_id();
322
323 per_cpu(cpu_data, cpu).idle = current;
324} 300}
325 301
326void __init smp_prepare_cpus(unsigned int max_cpus) 302void __init smp_prepare_cpus(unsigned int max_cpus)
@@ -454,6 +430,9 @@ static struct local_timer_ops *lt_ops;
454#ifdef CONFIG_LOCAL_TIMERS 430#ifdef CONFIG_LOCAL_TIMERS
455int local_timer_register(struct local_timer_ops *ops) 431int local_timer_register(struct local_timer_ops *ops)
456{ 432{
433 if (!is_smp() || !setup_max_cpus)
434 return -ENXIO;
435
457 if (lt_ops) 436 if (lt_ops)
458 return -EBUSY; 437 return -EBUSY;
459 438
diff --git a/arch/arm/kernel/smp_scu.c b/arch/arm/kernel/smp_scu.c
index 8f5dd7963356..b9f015e843d8 100644
--- a/arch/arm/kernel/smp_scu.c
+++ b/arch/arm/kernel/smp_scu.c
@@ -11,6 +11,7 @@
11#include <linux/init.h> 11#include <linux/init.h>
12#include <linux/io.h> 12#include <linux/io.h>
13 13
14#include <asm/smp_plat.h>
14#include <asm/smp_scu.h> 15#include <asm/smp_scu.h>
15#include <asm/cacheflush.h> 16#include <asm/cacheflush.h>
16#include <asm/cputype.h> 17#include <asm/cputype.h>
@@ -74,7 +75,7 @@ void scu_enable(void __iomem *scu_base)
74int scu_power_mode(void __iomem *scu_base, unsigned int mode) 75int scu_power_mode(void __iomem *scu_base, unsigned int mode)
75{ 76{
76 unsigned int val; 77 unsigned int val;
77 int cpu = smp_processor_id(); 78 int cpu = cpu_logical_map(smp_processor_id());
78 79
79 if (mode > 3 || mode == 1 || cpu > 3) 80 if (mode > 3 || mode == 1 || cpu > 3)
80 return -EINVAL; 81 return -EINVAL;
diff --git a/arch/arm/kernel/thumbee.c b/arch/arm/kernel/thumbee.c
index aab899764053..7b8403b76666 100644
--- a/arch/arm/kernel/thumbee.c
+++ b/arch/arm/kernel/thumbee.c
@@ -20,6 +20,7 @@
20#include <linux/kernel.h> 20#include <linux/kernel.h>
21#include <linux/init.h> 21#include <linux/init.h>
22 22
23#include <asm/cputype.h>
23#include <asm/system_info.h> 24#include <asm/system_info.h>
24#include <asm/thread_notify.h> 25#include <asm/thread_notify.h>
25 26
@@ -67,8 +68,7 @@ static int __init thumbee_init(void)
67 if (cpu_arch < CPU_ARCH_ARMv7) 68 if (cpu_arch < CPU_ARCH_ARMv7)
68 return 0; 69 return 0;
69 70
70 /* processor feature register 0 */ 71 pfr0 = read_cpuid_ext(CPUID_EXT_PFR0);
71 asm("mrc p15, 0, %0, c0, c1, 0\n" : "=r" (pfr0));
72 if ((pfr0 & 0x0000f000) != 0x00001000) 72 if ((pfr0 & 0x0000f000) != 0x00001000)
73 return 0; 73 return 0;
74 74
diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c
index fe31b22f18fd..af2afb019672 100644
--- a/arch/arm/kernel/time.c
+++ b/arch/arm/kernel/time.c
@@ -110,6 +110,42 @@ void timer_tick(void)
110} 110}
111#endif 111#endif
112 112
113static void dummy_clock_access(struct timespec *ts)
114{
115 ts->tv_sec = 0;
116 ts->tv_nsec = 0;
117}
118
119static clock_access_fn __read_persistent_clock = dummy_clock_access;
120static clock_access_fn __read_boot_clock = dummy_clock_access;;
121
122void read_persistent_clock(struct timespec *ts)
123{
124 __read_persistent_clock(ts);
125}
126
127void read_boot_clock(struct timespec *ts)
128{
129 __read_boot_clock(ts);
130}
131
132int __init register_persistent_clock(clock_access_fn read_boot,
133 clock_access_fn read_persistent)
134{
135 /* Only allow the clockaccess functions to be registered once */
136 if (__read_persistent_clock == dummy_clock_access &&
137 __read_boot_clock == dummy_clock_access) {
138 if (read_boot)
139 __read_boot_clock = read_boot;
140 if (read_persistent)
141 __read_persistent_clock = read_persistent;
142
143 return 0;
144 }
145
146 return -EINVAL;
147}
148
113#if defined(CONFIG_PM) && !defined(CONFIG_GENERIC_CLOCKEVENTS) 149#if defined(CONFIG_PM) && !defined(CONFIG_GENERIC_CLOCKEVENTS)
114static int timer_suspend(void) 150static int timer_suspend(void)
115{ 151{
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 5aef330e9c54..4928d89758f4 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -479,14 +479,14 @@ static int bad_syscall(int n, struct pt_regs *regs)
479 return regs->ARM_r0; 479 return regs->ARM_r0;
480} 480}
481 481
482static inline void 482static inline int
483do_cache_op(unsigned long start, unsigned long end, int flags) 483do_cache_op(unsigned long start, unsigned long end, int flags)
484{ 484{
485 struct mm_struct *mm = current->active_mm; 485 struct mm_struct *mm = current->active_mm;
486 struct vm_area_struct *vma; 486 struct vm_area_struct *vma;
487 487
488 if (end < start || flags) 488 if (end < start || flags)
489 return; 489 return -EINVAL;
490 490
491 down_read(&mm->mmap_sem); 491 down_read(&mm->mmap_sem);
492 vma = find_vma(mm, start); 492 vma = find_vma(mm, start);
@@ -496,9 +496,11 @@ do_cache_op(unsigned long start, unsigned long end, int flags)
496 if (end > vma->vm_end) 496 if (end > vma->vm_end)
497 end = vma->vm_end; 497 end = vma->vm_end;
498 498
499 flush_cache_user_range(vma, start, end); 499 up_read(&mm->mmap_sem);
500 return flush_cache_user_range(start, end);
500 } 501 }
501 up_read(&mm->mmap_sem); 502 up_read(&mm->mmap_sem);
503 return -EINVAL;
502} 504}
503 505
504/* 506/*
@@ -544,8 +546,7 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs)
544 * the specified region). 546 * the specified region).
545 */ 547 */
546 case NR(cacheflush): 548 case NR(cacheflush):
547 do_cache_op(regs->ARM_r0, regs->ARM_r1, regs->ARM_r2); 549 return do_cache_op(regs->ARM_r0, regs->ARM_r1, regs->ARM_r2);
548 return 0;
549 550
550 case NR(usr26): 551 case NR(usr26):
551 if (!(elf_hwcap & HWCAP_26BIT)) 552 if (!(elf_hwcap & HWCAP_26BIT))