diff options
author | Ingo Molnar <mingo@elte.hu> | 2008-10-03 19:28:46 +0200 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-10-03 19:28:46 +0200 |
commit | f68ec0c24755e5cdb779be6240925f2175311d84 (patch) | |
tree | a7b7128e61a8456385d82bd1c7ca5f14eecbf2ca /arch/avr32/kernel | |
parent | 98920dc3d1113b883cbc73e3293446d3525c6042 (diff) | |
parent | 94aca1dac6f6d21f4b07e4864baf7768cabcc6e7 (diff) | |
download | linux-f68ec0c24755e5cdb779be6240925f2175311d84.tar.gz |
Merge commit 'v2.6.27-rc8' into x86/setup
Diffstat (limited to 'arch/avr32/kernel')
-rw-r--r-- | arch/avr32/kernel/.gitignore | 1 | ||||
-rw-r--r-- | arch/avr32/kernel/asm-offsets.c | 6 | ||||
-rw-r--r-- | arch/avr32/kernel/avr32_ksyms.c | 1 | ||||
-rw-r--r-- | arch/avr32/kernel/cpu.c | 38 | ||||
-rw-r--r-- | arch/avr32/kernel/entry-avr32b.S | 59 | ||||
-rw-r--r-- | arch/avr32/kernel/process.c | 4 | ||||
-rw-r--r-- | arch/avr32/kernel/setup.c | 4 | ||||
-rw-r--r-- | arch/avr32/kernel/stacktrace.c | 1 | ||||
-rw-r--r-- | arch/avr32/kernel/syscall-stubs.S | 9 | ||||
-rw-r--r-- | arch/avr32/kernel/syscall_table.S | 2 | ||||
-rw-r--r-- | arch/avr32/kernel/time.c | 8 | ||||
-rw-r--r-- | arch/avr32/kernel/traps.c | 8 |
12 files changed, 115 insertions, 26 deletions
diff --git a/arch/avr32/kernel/.gitignore b/arch/avr32/kernel/.gitignore new file mode 100644 index 000000000000..c5f676c3c224 --- /dev/null +++ b/arch/avr32/kernel/.gitignore @@ -0,0 +1 @@ +vmlinux.lds diff --git a/arch/avr32/kernel/asm-offsets.c b/arch/avr32/kernel/asm-offsets.c index e4796c67a831..d6a8193a1d2f 100644 --- a/arch/avr32/kernel/asm-offsets.c +++ b/arch/avr32/kernel/asm-offsets.c @@ -4,6 +4,8 @@ * to extract and format the required data. */ +#include <linux/mm.h> +#include <linux/sched.h> #include <linux/thread_info.h> #include <linux/kbuild.h> @@ -17,4 +19,8 @@ void foo(void) OFFSET(TI_rar_saved, thread_info, rar_saved); OFFSET(TI_rsr_saved, thread_info, rsr_saved); OFFSET(TI_restart_block, thread_info, restart_block); + BLANK(); + OFFSET(TSK_active_mm, task_struct, active_mm); + BLANK(); + OFFSET(MM_pgd, mm_struct, pgd); } diff --git a/arch/avr32/kernel/avr32_ksyms.c b/arch/avr32/kernel/avr32_ksyms.c index 84a7d44edc67..11e310c567a9 100644 --- a/arch/avr32/kernel/avr32_ksyms.c +++ b/arch/avr32/kernel/avr32_ksyms.c @@ -58,6 +58,7 @@ EXPORT_SYMBOL(find_first_zero_bit); EXPORT_SYMBOL(find_next_zero_bit); EXPORT_SYMBOL(find_first_bit); EXPORT_SYMBOL(find_next_bit); +EXPORT_SYMBOL(generic_find_next_le_bit); EXPORT_SYMBOL(generic_find_next_zero_le_bit); /* I/O primitives (lib/io-*.S) */ diff --git a/arch/avr32/kernel/cpu.c b/arch/avr32/kernel/cpu.c index b8409caeb23d..e84faffbbeca 100644 --- a/arch/avr32/kernel/cpu.c +++ b/arch/avr32/kernel/cpu.c @@ -26,14 +26,16 @@ static DEFINE_PER_CPU(struct cpu, cpu_devices); * XXX: If/when a SMP-capable implementation of AVR32 will ever be * made, we must make sure that the code executes on the correct CPU. */ -static ssize_t show_pc0event(struct sys_device *dev, char *buf) +static ssize_t show_pc0event(struct sys_device *dev, + struct sysdev_attribute *attr, char *buf) { unsigned long pccr; pccr = sysreg_read(PCCR); return sprintf(buf, "0x%lx\n", (pccr >> 12) & 0x3f); } -static ssize_t store_pc0event(struct sys_device *dev, const char *buf, +static ssize_t store_pc0event(struct sys_device *dev, + struct sysdev_attribute *attr, const char *buf, size_t count) { unsigned long val; @@ -46,15 +48,17 @@ static ssize_t store_pc0event(struct sys_device *dev, const char *buf, sysreg_write(PCCR, val); return count; } -static ssize_t show_pc0count(struct sys_device *dev, char *buf) +static ssize_t show_pc0count(struct sys_device *dev, + struct sysdev_attribute *attr, char *buf) { unsigned long pcnt0; pcnt0 = sysreg_read(PCNT0); return sprintf(buf, "%lu\n", pcnt0); } -static ssize_t store_pc0count(struct sys_device *dev, const char *buf, - size_t count) +static ssize_t store_pc0count(struct sys_device *dev, + struct sysdev_attribute *attr, + const char *buf, size_t count) { unsigned long val; char *endp; @@ -67,14 +71,16 @@ static ssize_t store_pc0count(struct sys_device *dev, const char *buf, return count; } -static ssize_t show_pc1event(struct sys_device *dev, char *buf) +static ssize_t show_pc1event(struct sys_device *dev, + struct sysdev_attribute *attr, char *buf) { unsigned long pccr; pccr = sysreg_read(PCCR); return sprintf(buf, "0x%lx\n", (pccr >> 18) & 0x3f); } -static ssize_t store_pc1event(struct sys_device *dev, const char *buf, +static ssize_t store_pc1event(struct sys_device *dev, + struct sysdev_attribute *attr, const char *buf, size_t count) { unsigned long val; @@ -87,14 +93,16 @@ static ssize_t store_pc1event(struct sys_device *dev, const char *buf, sysreg_write(PCCR, val); return count; } -static ssize_t show_pc1count(struct sys_device *dev, char *buf) +static ssize_t show_pc1count(struct sys_device *dev, + struct sysdev_attribute *attr, char *buf) { unsigned long pcnt1; pcnt1 = sysreg_read(PCNT1); return sprintf(buf, "%lu\n", pcnt1); } -static ssize_t store_pc1count(struct sys_device *dev, const char *buf, +static ssize_t store_pc1count(struct sys_device *dev, + struct sysdev_attribute *attr, const char *buf, size_t count) { unsigned long val; @@ -108,14 +116,16 @@ static ssize_t store_pc1count(struct sys_device *dev, const char *buf, return count; } -static ssize_t show_pccycles(struct sys_device *dev, char *buf) +static ssize_t show_pccycles(struct sys_device *dev, + struct sysdev_attribute *attr, char *buf) { unsigned long pccnt; pccnt = sysreg_read(PCCNT); return sprintf(buf, "%lu\n", pccnt); } -static ssize_t store_pccycles(struct sys_device *dev, const char *buf, +static ssize_t store_pccycles(struct sys_device *dev, + struct sysdev_attribute *attr, const char *buf, size_t count) { unsigned long val; @@ -129,14 +139,16 @@ static ssize_t store_pccycles(struct sys_device *dev, const char *buf, return count; } -static ssize_t show_pcenable(struct sys_device *dev, char *buf) +static ssize_t show_pcenable(struct sys_device *dev, + struct sysdev_attribute *attr, char *buf) { unsigned long pccr; pccr = sysreg_read(PCCR); return sprintf(buf, "%c\n", (pccr & 1)?'1':'0'); } -static ssize_t store_pcenable(struct sys_device *dev, const char *buf, +static ssize_t store_pcenable(struct sys_device *dev, + struct sysdev_attribute *attr, const char *buf, size_t count) { unsigned long pccr, val; diff --git a/arch/avr32/kernel/entry-avr32b.S b/arch/avr32/kernel/entry-avr32b.S index 2b398cae110c..33d49377b8be 100644 --- a/arch/avr32/kernel/entry-avr32b.S +++ b/arch/avr32/kernel/entry-avr32b.S @@ -334,9 +334,64 @@ save_full_context_ex: /* Low-level exception handlers */ handle_critical: + /* + * AT32AP700x errata: + * + * After a Java stack overflow or underflow trap, any CPU + * memory access may cause erratic behavior. This will happen + * when the four least significant bits of the JOSP system + * register contains any value between 9 and 15 (inclusive). + * + * Possible workarounds: + * - Don't use the Java Extension Module + * - Ensure that the stack overflow and underflow trap + * handlers do not do any memory access or trigger any + * exceptions before the overflow/underflow condition is + * cleared (by incrementing or decrementing the JOSP) + * - Make sure that JOSP does not contain any problematic + * value before doing any exception or interrupt + * processing. + * - Set up a critical exception handler which writes a + * known-to-be-safe value, e.g. 4, to JOSP before doing + * any further processing. + * + * We'll use the last workaround for now since we cannot + * guarantee that user space processes don't use Java mode. + * Non-well-behaving userland will be terminated with extreme + * prejudice. + */ +#ifdef CONFIG_CPU_AT32AP700X + /* + * There's a chance we can't touch memory, so temporarily + * borrow PTBR to save the stack pointer while we fix things + * up... + */ + mtsr SYSREG_PTBR, sp + mov sp, 4 + mtsr SYSREG_JOSP, sp + mfsr sp, SYSREG_PTBR + sub pc, -2 + + /* Push most of pt_regs on stack. We'll do the rest later */ sub sp, 4 - stmts --sp, r0-lr - rcall save_full_context_ex + pushm r0-r12 + + /* PTBR mirrors current_thread_info()->task->active_mm->pgd */ + get_thread_info r0 + ld.w r1, r0[TI_task] + ld.w r2, r1[TSK_active_mm] + ld.w r3, r2[MM_pgd] + mtsr SYSREG_PTBR, r3 +#else + sub sp, 4 + pushm r0-r12 +#endif + sub r0, sp, -(14 * 4) + mov r1, lr + mfsr r2, SYSREG_RAR_EX + mfsr r3, SYSREG_RSR_EX + pushm r0-r3 + mfsr r12, SYSREG_ECR mov r11, sp rcall do_critical_exception diff --git a/arch/avr32/kernel/process.c b/arch/avr32/kernel/process.c index 6cf9df176274..2c08ac992ac3 100644 --- a/arch/avr32/kernel/process.c +++ b/arch/avr32/kernel/process.c @@ -18,7 +18,7 @@ #include <asm/sysreg.h> #include <asm/ocd.h> -#include <asm/arch/pm.h> +#include <mach/pm.h> void (*pm_power_off)(void) = NULL; EXPORT_SYMBOL(pm_power_off); @@ -31,7 +31,7 @@ void cpu_idle(void) { /* endless idle loop with no priority at all */ while (1) { - tick_nohz_stop_sched_tick(); + tick_nohz_stop_sched_tick(1); while (!need_resched()) cpu_idle_sleep(); tick_nohz_restart_sched_tick(); diff --git a/arch/avr32/kernel/setup.c b/arch/avr32/kernel/setup.c index ce48c14f4349..d8e623c426c1 100644 --- a/arch/avr32/kernel/setup.c +++ b/arch/avr32/kernel/setup.c @@ -26,8 +26,8 @@ #include <asm/setup.h> #include <asm/sysreg.h> -#include <asm/arch/board.h> -#include <asm/arch/init.h> +#include <mach/board.h> +#include <mach/init.h> extern int root_mountflags; diff --git a/arch/avr32/kernel/stacktrace.c b/arch/avr32/kernel/stacktrace.c index f4bdb448049c..c09f0d8dd679 100644 --- a/arch/avr32/kernel/stacktrace.c +++ b/arch/avr32/kernel/stacktrace.c @@ -10,6 +10,7 @@ #include <linux/sched.h> #include <linux/stacktrace.h> #include <linux/thread_info.h> +#include <linux/module.h> register unsigned long current_frame_pointer asm("r7"); diff --git a/arch/avr32/kernel/syscall-stubs.S b/arch/avr32/kernel/syscall-stubs.S index 890286a1e62b..673178e235f3 100644 --- a/arch/avr32/kernel/syscall-stubs.S +++ b/arch/avr32/kernel/syscall-stubs.S @@ -109,3 +109,12 @@ __sys_epoll_pwait: rcall sys_epoll_pwait sub sp, -4 popm pc + + .global __sys_sync_file_range + .type __sys_sync_file_range,@function +__sys_sync_file_range: + pushm lr + st.w --sp, ARG6 + rcall sys_sync_file_range + sub sp, -4 + popm pc diff --git a/arch/avr32/kernel/syscall_table.S b/arch/avr32/kernel/syscall_table.S index 478bda4c4a09..7ee0057613b3 100644 --- a/arch/avr32/kernel/syscall_table.S +++ b/arch/avr32/kernel/syscall_table.S @@ -275,7 +275,7 @@ sys_call_table: .long sys_set_robust_list .long sys_get_robust_list /* 260 */ .long __sys_splice - .long sys_sync_file_range + .long __sys_sync_file_range .long sys_tee .long sys_vmsplice .long __sys_epoll_pwait /* 265 */ diff --git a/arch/avr32/kernel/time.c b/arch/avr32/kernel/time.c index abd954fb7ba0..283481d74a5b 100644 --- a/arch/avr32/kernel/time.c +++ b/arch/avr32/kernel/time.c @@ -15,7 +15,7 @@ #include <asm/sysreg.h> -#include <asm/arch/pm.h> +#include <mach/pm.h> static cycle_t read_cycle_count(void) @@ -43,6 +43,9 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id) { struct clock_event_device *evdev = dev_id; + if (unlikely(!(intc_get_pending(0) & 1))) + return IRQ_NONE; + /* * Disable the interrupt until the clockevent subsystem * reprograms it. @@ -55,7 +58,8 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id) static struct irqaction timer_irqaction = { .handler = timer_interrupt, - .flags = IRQF_TIMER | IRQF_DISABLED, + /* Oprofile uses the same irq as the timer, so allow it to be shared */ + .flags = IRQF_TIMER | IRQF_DISABLED | IRQF_SHARED, .name = "avr32_comparator", }; diff --git a/arch/avr32/kernel/traps.c b/arch/avr32/kernel/traps.c index b835c4c01368..0d987373bc01 100644 --- a/arch/avr32/kernel/traps.c +++ b/arch/avr32/kernel/traps.c @@ -116,15 +116,15 @@ asmlinkage void do_nmi(unsigned long ecr, struct pt_regs *regs) switch (ret) { case NOTIFY_OK: case NOTIFY_STOP: - return; + break; case NOTIFY_BAD: die("Fatal Non-Maskable Interrupt", regs, SIGINT); default: + printk(KERN_ALERT "Got NMI, but nobody cared. Disabling...\n"); + nmi_disable(); break; } - - printk(KERN_ALERT "Got NMI, but nobody cared. Disabling...\n"); - nmi_disable(); + nmi_exit(); } asmlinkage void do_critical_exception(unsigned long ecr, struct pt_regs *regs) |