diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-02-19 16:18:39 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-02-19 16:18:39 -0500 |
commit | 59b8175c771040afcd4ad67022b0cc80c216b866 (patch) | |
tree | 4ef5935bee1e342716d49b9d4b99e3fa835526e6 /arch/arm/kernel | |
parent | 920841d8d1d61bc12b43f95a579a5374f6d98f81 (diff) | |
parent | 3b0eb4a195a124567cd0dd6f700f8388def542c6 (diff) |
Merge branch 'for-linus' of master.kernel.org:/home/rmk/linux-2.6-arm
* 'for-linus' of master.kernel.org:/home/rmk/linux-2.6-arm: (117 commits)
[ARM] 4058/2: iop32x: set ->broken_parity_status on n2100 onboard r8169 ports
[ARM] 4140/1: AACI stability add ac97 timeout and retries
[ARM] 4139/1: AACI record support
[ARM] 4138/1: AACI: multiple channel support for IRQ handling
[ARM] 4211/1: Provide a defconfig for ns9xxx
[ARM] 4210/1: base for new machine type "NetSilicon NS9360"
[ARM] 4222/1: S3C2443: Remove reference to missing S3C2443_PM
[ARM] 4221/1: S3C2443: DMA support
[ARM] 4220/1: S3C24XX: DMA system initialised from sysdev
[ARM] 4219/1: S3C2443: DMA source definitions
[ARM] 4218/1: S3C2412: fix CONFIG_CPU_S3C2412_ONLY wrt to S3C2443
[ARM] 4217/1: S3C24XX: remove the dma channel show at startup
[ARM] 4090/2: avoid clash between PXA and SA1111 defines
[ARM] 4216/1: add .gitignore entries for ARM specific files
[ARM] 4214/2: S3C2410: Add Armzone QT2410
[ARM] 4215/1: s3c2410 usb device: per-platform vbus_draw
[ARM] 4213/1: S3C2410 - Update definition of ADCTSC_XY_PST
[ARM] 4098/1: ARM: rtc_lock only used with rtc_cmos
[ARM] 4137/1: Add kexec support
[ARM] 4201/1: SMP barriers pair needed for the secondary boot process
...
Fix up conflict due to typedef removal in sound/arm/aaci.h
Diffstat (limited to 'arch/arm/kernel')
-rw-r--r-- | arch/arm/kernel/Makefile | 1 | ||||
-rw-r--r-- | arch/arm/kernel/calls.S | 1 | ||||
-rw-r--r-- | arch/arm/kernel/crunch.c | 1 | ||||
-rw-r--r-- | arch/arm/kernel/ecard.c | 2 | ||||
-rw-r--r-- | arch/arm/kernel/entry-armv.S | 1 | ||||
-rw-r--r-- | arch/arm/kernel/machine_kexec.c | 78 | ||||
-rw-r--r-- | arch/arm/kernel/process.c | 8 | ||||
-rw-r--r-- | arch/arm/kernel/relocate_kernel.S | 74 | ||||
-rw-r--r-- | arch/arm/kernel/setup.c | 3 | ||||
-rw-r--r-- | arch/arm/kernel/time.c | 4 | ||||
-rw-r--r-- | arch/arm/kernel/traps.c | 17 |
11 files changed, 175 insertions, 15 deletions
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index 1b935fb94b83..bb28087bf818 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile | |||
@@ -18,6 +18,7 @@ obj-$(CONFIG_ARTHUR) += arthur.o | |||
18 | obj-$(CONFIG_ISA_DMA) += dma-isa.o | 18 | obj-$(CONFIG_ISA_DMA) += dma-isa.o |
19 | obj-$(CONFIG_PCI) += bios32.o isa.o | 19 | obj-$(CONFIG_PCI) += bios32.o isa.o |
20 | obj-$(CONFIG_SMP) += smp.o | 20 | obj-$(CONFIG_SMP) += smp.o |
21 | obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o | ||
21 | obj-$(CONFIG_OABI_COMPAT) += sys_oabi-compat.o | 22 | obj-$(CONFIG_OABI_COMPAT) += sys_oabi-compat.o |
22 | 23 | ||
23 | obj-$(CONFIG_CRUNCH) += crunch.o crunch-bits.o | 24 | obj-$(CONFIG_CRUNCH) += crunch.o crunch-bits.o |
diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S index f7598cbc7ec5..ae89cdd82b16 100644 --- a/arch/arm/kernel/calls.S +++ b/arch/arm/kernel/calls.S | |||
@@ -356,6 +356,7 @@ | |||
356 | CALL(sys_move_pages) | 356 | CALL(sys_move_pages) |
357 | /* 345 */ CALL(sys_getcpu) | 357 | /* 345 */ CALL(sys_getcpu) |
358 | CALL(sys_ni_syscall) /* eventually epoll_pwait */ | 358 | CALL(sys_ni_syscall) /* eventually epoll_pwait */ |
359 | CALL(sys_kexec_load) | ||
359 | #ifndef syscalls_counted | 360 | #ifndef syscalls_counted |
360 | .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls | 361 | .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls |
361 | #define syscalls_counted | 362 | #define syscalls_counted |
diff --git a/arch/arm/kernel/crunch.c b/arch/arm/kernel/crunch.c index cec83783206e..627d79414c9d 100644 --- a/arch/arm/kernel/crunch.c +++ b/arch/arm/kernel/crunch.c | |||
@@ -75,6 +75,7 @@ static struct notifier_block crunch_notifier_block = { | |||
75 | static int __init crunch_init(void) | 75 | static int __init crunch_init(void) |
76 | { | 76 | { |
77 | thread_register_notifier(&crunch_notifier_block); | 77 | thread_register_notifier(&crunch_notifier_block); |
78 | elf_hwcap |= HWCAP_CRUNCH; | ||
78 | 79 | ||
79 | return 0; | 80 | return 0; |
80 | } | 81 | } |
diff --git a/arch/arm/kernel/ecard.c b/arch/arm/kernel/ecard.c index 71257e3d513f..f1c0fb974177 100644 --- a/arch/arm/kernel/ecard.c +++ b/arch/arm/kernel/ecard.c | |||
@@ -1009,7 +1009,7 @@ ecard_probe(int slot, card_type_t type) | |||
1009 | ec->fiqmask = 4; | 1009 | ec->fiqmask = 4; |
1010 | } | 1010 | } |
1011 | 1011 | ||
1012 | for (i = 0; i < sizeof(blacklist) / sizeof(*blacklist); i++) | 1012 | for (i = 0; i < ARRAY_SIZE(blacklist); i++) |
1013 | if (blacklist[i].manufacturer == ec->cid.manufacturer && | 1013 | if (blacklist[i].manufacturer == ec->cid.manufacturer && |
1014 | blacklist[i].product == ec->cid.product) { | 1014 | blacklist[i].product == ec->cid.product) { |
1015 | ec->card_desc = blacklist[i].type; | 1015 | ec->card_desc = blacklist[i].type; |
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index 8517c3c3eb33..cc10a093a545 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S | |||
@@ -99,7 +99,6 @@ common_invalid: | |||
99 | @ cpsr_<exception>, "old_r0" | 99 | @ cpsr_<exception>, "old_r0" |
100 | 100 | ||
101 | mov r0, sp | 101 | mov r0, sp |
102 | and r2, r6, #0x1f | ||
103 | b bad_mode | 102 | b bad_mode |
104 | 103 | ||
105 | /* | 104 | /* |
diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c new file mode 100644 index 000000000000..863c66454f2b --- /dev/null +++ b/arch/arm/kernel/machine_kexec.c | |||
@@ -0,0 +1,78 @@ | |||
1 | /* | ||
2 | * machine_kexec.c - handle transition of Linux booting another kernel | ||
3 | */ | ||
4 | |||
5 | #include <linux/mm.h> | ||
6 | #include <linux/kexec.h> | ||
7 | #include <linux/delay.h> | ||
8 | #include <linux/reboot.h> | ||
9 | #include <asm/pgtable.h> | ||
10 | #include <asm/pgalloc.h> | ||
11 | #include <asm/mmu_context.h> | ||
12 | #include <asm/io.h> | ||
13 | #include <asm/cacheflush.h> | ||
14 | #include <asm/mach-types.h> | ||
15 | |||
16 | const extern unsigned char relocate_new_kernel[]; | ||
17 | const extern unsigned int relocate_new_kernel_size; | ||
18 | |||
19 | extern void setup_mm_for_reboot(char mode); | ||
20 | |||
21 | extern unsigned long kexec_start_address; | ||
22 | extern unsigned long kexec_indirection_page; | ||
23 | extern unsigned long kexec_mach_type; | ||
24 | |||
25 | /* | ||
26 | * Provide a dummy crash_notes definition while crash dump arrives to arm. | ||
27 | * This prevents breakage of crash_notes attribute in kernel/ksysfs.c. | ||
28 | */ | ||
29 | |||
30 | int machine_kexec_prepare(struct kimage *image) | ||
31 | { | ||
32 | return 0; | ||
33 | } | ||
34 | |||
35 | void machine_kexec_cleanup(struct kimage *image) | ||
36 | { | ||
37 | } | ||
38 | |||
39 | void machine_shutdown(void) | ||
40 | { | ||
41 | } | ||
42 | |||
43 | void machine_crash_shutdown(struct pt_regs *regs) | ||
44 | { | ||
45 | } | ||
46 | |||
47 | void machine_kexec(struct kimage *image) | ||
48 | { | ||
49 | unsigned long page_list; | ||
50 | unsigned long reboot_code_buffer_phys; | ||
51 | void *reboot_code_buffer; | ||
52 | |||
53 | |||
54 | page_list = image->head & PAGE_MASK; | ||
55 | |||
56 | /* we need both effective and real address here */ | ||
57 | reboot_code_buffer_phys = | ||
58 | page_to_pfn(image->control_code_page) << PAGE_SHIFT; | ||
59 | reboot_code_buffer = page_address(image->control_code_page); | ||
60 | |||
61 | /* Prepare parameters for reboot_code_buffer*/ | ||
62 | kexec_start_address = image->start; | ||
63 | kexec_indirection_page = page_list; | ||
64 | kexec_mach_type = machine_arch_type; | ||
65 | |||
66 | /* copy our kernel relocation code to the control code page */ | ||
67 | memcpy(reboot_code_buffer, | ||
68 | relocate_new_kernel, relocate_new_kernel_size); | ||
69 | |||
70 | |||
71 | flush_icache_range((unsigned long) reboot_code_buffer, | ||
72 | (unsigned long) reboot_code_buffer + KEXEC_CONTROL_CODE_SIZE); | ||
73 | printk(KERN_INFO "Bye!\n"); | ||
74 | |||
75 | cpu_proc_fin(); | ||
76 | setup_mm_for_reboot(0); /* mode is not used, so just pass 0*/ | ||
77 | cpu_reset(reboot_code_buffer_phys); | ||
78 | } | ||
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index a9e8f7e55fd6..782af3cb213f 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c | |||
@@ -36,7 +36,13 @@ | |||
36 | #include <asm/uaccess.h> | 36 | #include <asm/uaccess.h> |
37 | #include <asm/mach/time.h> | 37 | #include <asm/mach/time.h> |
38 | 38 | ||
39 | extern const char *processor_modes[]; | 39 | static const char *processor_modes[] = { |
40 | "USER_26", "FIQ_26" , "IRQ_26" , "SVC_26" , "UK4_26" , "UK5_26" , "UK6_26" , "UK7_26" , | ||
41 | "UK8_26" , "UK9_26" , "UK10_26", "UK11_26", "UK12_26", "UK13_26", "UK14_26", "UK15_26", | ||
42 | "USER_32", "FIQ_32" , "IRQ_32" , "SVC_32" , "UK4_32" , "UK5_32" , "UK6_32" , "ABT_32" , | ||
43 | "UK8_32" , "UK9_32" , "UK10_32", "UND_32" , "UK12_32", "UK13_32", "UK14_32", "SYS_32" | ||
44 | }; | ||
45 | |||
40 | extern void setup_mm_for_reboot(char mode); | 46 | extern void setup_mm_for_reboot(char mode); |
41 | 47 | ||
42 | static volatile int hlt_counter; | 48 | static volatile int hlt_counter; |
diff --git a/arch/arm/kernel/relocate_kernel.S b/arch/arm/kernel/relocate_kernel.S new file mode 100644 index 000000000000..7baadae7cb27 --- /dev/null +++ b/arch/arm/kernel/relocate_kernel.S | |||
@@ -0,0 +1,74 @@ | |||
1 | /* | ||
2 | * relocate_kernel.S - put the kernel image in place to boot | ||
3 | */ | ||
4 | |||
5 | #include <asm/kexec.h> | ||
6 | |||
7 | .globl relocate_new_kernel | ||
8 | relocate_new_kernel: | ||
9 | |||
10 | ldr r0,kexec_indirection_page | ||
11 | ldr r1,kexec_start_address | ||
12 | |||
13 | |||
14 | 0: /* top, read another word for the indirection page */ | ||
15 | ldr r3, [r0],#4 | ||
16 | |||
17 | /* Is it a destination page. Put destination address to r4 */ | ||
18 | tst r3,#1,0 | ||
19 | beq 1f | ||
20 | bic r4,r3,#1 | ||
21 | b 0b | ||
22 | 1: | ||
23 | /* Is it an indirection page */ | ||
24 | tst r3,#2,0 | ||
25 | beq 1f | ||
26 | bic r0,r3,#2 | ||
27 | b 0b | ||
28 | 1: | ||
29 | |||
30 | /* are we done ? */ | ||
31 | tst r3,#4,0 | ||
32 | beq 1f | ||
33 | b 2f | ||
34 | |||
35 | 1: | ||
36 | /* is it source ? */ | ||
37 | tst r3,#8,0 | ||
38 | beq 0b | ||
39 | bic r3,r3,#8 | ||
40 | mov r6,#1024 | ||
41 | 9: | ||
42 | ldr r5,[r3],#4 | ||
43 | str r5,[r4],#4 | ||
44 | subs r6,r6,#1 | ||
45 | bne 9b | ||
46 | b 0b | ||
47 | |||
48 | 2: | ||
49 | /* Jump to relocated kernel */ | ||
50 | mov lr,r1 | ||
51 | mov r0,#0 | ||
52 | ldr r1,kexec_mach_type | ||
53 | mov r2,#0 | ||
54 | mov pc,lr | ||
55 | |||
56 | .globl kexec_start_address | ||
57 | kexec_start_address: | ||
58 | .long 0x0 | ||
59 | |||
60 | .globl kexec_indirection_page | ||
61 | kexec_indirection_page: | ||
62 | .long 0x0 | ||
63 | |||
64 | .globl kexec_mach_type | ||
65 | kexec_mach_type: | ||
66 | .long 0x0 | ||
67 | |||
68 | relocate_new_kernel_end: | ||
69 | |||
70 | .globl relocate_new_kernel_size | ||
71 | relocate_new_kernel_size: | ||
72 | .long relocate_new_kernel_end - relocate_new_kernel | ||
73 | |||
74 | |||
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index ed522151878b..03e37af315d7 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c | |||
@@ -88,6 +88,9 @@ struct cpu_user_fns cpu_user; | |||
88 | #ifdef MULTI_CACHE | 88 | #ifdef MULTI_CACHE |
89 | struct cpu_cache_fns cpu_cache; | 89 | struct cpu_cache_fns cpu_cache; |
90 | #endif | 90 | #endif |
91 | #ifdef CONFIG_OUTER_CACHE | ||
92 | struct outer_cache_fns outer_cache; | ||
93 | #endif | ||
91 | 94 | ||
92 | struct stack { | 95 | struct stack { |
93 | u32 irq[3]; | 96 | u32 irq[3]; |
diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c index ee47c532e210..f61decb89ba2 100644 --- a/arch/arm/kernel/time.c +++ b/arch/arm/kernel/time.c | |||
@@ -40,12 +40,14 @@ | |||
40 | */ | 40 | */ |
41 | struct sys_timer *system_timer; | 41 | struct sys_timer *system_timer; |
42 | 42 | ||
43 | #if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE) | ||
43 | /* this needs a better home */ | 44 | /* this needs a better home */ |
44 | DEFINE_SPINLOCK(rtc_lock); | 45 | DEFINE_SPINLOCK(rtc_lock); |
45 | 46 | ||
46 | #ifdef CONFIG_SA1100_RTC_MODULE | 47 | #ifdef CONFIG_RTC_DRV_CMOS_MODULE |
47 | EXPORT_SYMBOL(rtc_lock); | 48 | EXPORT_SYMBOL(rtc_lock); |
48 | #endif | 49 | #endif |
50 | #endif /* pc-style 'CMOS' RTC support */ | ||
49 | 51 | ||
50 | /* change this if you have some constant time drift */ | 52 | /* change this if you have some constant time drift */ |
51 | #define USECS_PER_JIFFY (1000000/HZ) | 53 | #define USECS_PER_JIFFY (1000000/HZ) |
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index 908915675edc..24095601359b 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c | |||
@@ -32,13 +32,6 @@ | |||
32 | #include "ptrace.h" | 32 | #include "ptrace.h" |
33 | #include "signal.h" | 33 | #include "signal.h" |
34 | 34 | ||
35 | const char *processor_modes[]= | ||
36 | { "USER_26", "FIQ_26" , "IRQ_26" , "SVC_26" , "UK4_26" , "UK5_26" , "UK6_26" , "UK7_26" , | ||
37 | "UK8_26" , "UK9_26" , "UK10_26", "UK11_26", "UK12_26", "UK13_26", "UK14_26", "UK15_26", | ||
38 | "USER_32", "FIQ_32" , "IRQ_32" , "SVC_32" , "UK4_32" , "UK5_32" , "UK6_32" , "ABT_32" , | ||
39 | "UK8_32" , "UK9_32" , "UK10_32", "UND_32" , "UK12_32", "UK13_32", "UK14_32", "SYS_32" | ||
40 | }; | ||
41 | |||
42 | static const char *handler[]= { "prefetch abort", "data abort", "address exception", "interrupt" }; | 35 | static const char *handler[]= { "prefetch abort", "data abort", "address exception", "interrupt" }; |
43 | 36 | ||
44 | #ifdef CONFIG_DEBUG_USER | 37 | #ifdef CONFIG_DEBUG_USER |
@@ -289,7 +282,10 @@ asmlinkage void do_undefinstr(struct pt_regs *regs) | |||
289 | regs->ARM_pc -= correction; | 282 | regs->ARM_pc -= correction; |
290 | 283 | ||
291 | pc = (void __user *)instruction_pointer(regs); | 284 | pc = (void __user *)instruction_pointer(regs); |
292 | if (thumb_mode(regs)) { | 285 | |
286 | if (processor_mode(regs) == SVC_MODE) { | ||
287 | instr = *(u32 *) pc; | ||
288 | } else if (thumb_mode(regs)) { | ||
293 | get_user(instr, (u16 __user *)pc); | 289 | get_user(instr, (u16 __user *)pc); |
294 | } else { | 290 | } else { |
295 | get_user(instr, (u32 __user *)pc); | 291 | get_user(instr, (u32 __user *)pc); |
@@ -337,12 +333,11 @@ asmlinkage void do_unexp_fiq (struct pt_regs *regs) | |||
337 | * It never returns, and never tries to sync. We hope that we can at least | 333 | * It never returns, and never tries to sync. We hope that we can at least |
338 | * dump out some state information... | 334 | * dump out some state information... |
339 | */ | 335 | */ |
340 | asmlinkage void bad_mode(struct pt_regs *regs, int reason, int proc_mode) | 336 | asmlinkage void bad_mode(struct pt_regs *regs, int reason) |
341 | { | 337 | { |
342 | console_verbose(); | 338 | console_verbose(); |
343 | 339 | ||
344 | printk(KERN_CRIT "Bad mode in %s handler detected: mode %s\n", | 340 | printk(KERN_CRIT "Bad mode in %s handler detected\n", handler[reason]); |
345 | handler[reason], processor_modes[proc_mode]); | ||
346 | 341 | ||
347 | die("Oops - bad mode", regs, 0); | 342 | die("Oops - bad mode", regs, 0); |
348 | local_irq_disable(); | 343 | local_irq_disable(); |