GIT 18098f5af99862f9fab3cf13afee804d4a1d891d git+ssh://master.kernel.org/home/rmk/linux-2.6-arm.git#devel commit Author: Russell King Date: Sun Mar 4 20:44:59 2007 +0000 [ARM] getuser.S and putuser.S don't need thread_info.h nor asm-offsets.h Signed-off-by: Russell King commit 39d05384baed484544e88fbbe5612c4187da0bab Author: Russell King Date: Sun Mar 4 09:50:28 2007 +0000 [ARM] ptrace: clean up single stepping support Signed-off-by: Russell King commit b4d04f3470303bbca601c42b31065551240ec986 Author: Russell King Date: Sat Mar 3 19:45:25 2007 +0000 [ARM] Remove needless linux/ptrace.h includes Lots of places in arch/arm were needlessly including linux/ptrace.h, resumably because we used to pass a struct pt_regs to interrupt handlers. Now that we don't, all these ptrace.h includes are redundant. Signed-off-by: Russell King commit b719353cd4053d754402b1e9b12eae6deb446f3e Author: Philipp Zabel Date: Mon Feb 26 01:44:57 2007 +0100 [ARM] 4236/2: basic {enable,disable}_irq_wake() support for PXA pxa_set_gpio_wake handles GPIOs > 1, so IRQ_TO_GPIO has to be used instead of just substracting IRQ_GPIO0 from the irq number. --- GPIO support tested on MACH_MAGICIAN (PXA27x) with a CPLD wakeup source on GPIO 13. Signed-off-by: Philipp Zabel Signed-off-by: Russell King commit 1f8210843bffe08c97da58d5bf48ce968251247f Author: Russell King Date: Sat Mar 3 11:51:31 2007 +0000 [ARM] EBSA110: Add readsw/readsl/writesw/writesl Signed-off-by: Russell King commit 996ea9dbad68a2cb19ed6552eed575221703f2ea Author: Russell King Date: Fri Mar 2 15:01:36 2007 +0000 [ARM] Add ability to dump exception stacks to kernel backtraces Signed-off-by: Russell King arch/arm/common/sa1111.c | 1 arch/arm/common/via82c505.c | 1 arch/arm/kernel/irq.c | 3 - arch/arm/kernel/process.c | 1 arch/arm/kernel/ptrace.c | 15 +-- arch/arm/kernel/ptrace.h | 39 ++++++++ arch/arm/kernel/signal.c | 22 +---- arch/arm/kernel/traps.c | 19 +++- arch/arm/kernel/vmlinux.lds.S | 3 + arch/arm/lib/backtrace.S | 165 +++++++++++++++++----------------- arch/arm/lib/getuser.S | 2 arch/arm/lib/putuser.S | 2 arch/arm/mach-ebsa110/io.c | 40 ++++++++ arch/arm/mach-footbridge/dc21285.c | 1 arch/arm/mach-integrator/pci.c | 1 arch/arm/mach-integrator/pci_v3.c | 1 arch/arm/mach-lh7a40x/irq-lh7a400.c | 1 arch/arm/mach-lh7a40x/irq-lh7a404.c | 1 arch/arm/mach-lh7a40x/irq-lpd7a40x.c | 1 arch/arm/mach-omap1/irq.c | 1 arch/arm/mach-pxa/irq.c | 73 ++++++++++++++- arch/arm/mach-s3c2410/bast-irq.c | 1 arch/arm/mach-s3c2410/irq.c | 1 arch/arm/mach-s3c2412/irq.c | 1 arch/arm/mach-s3c2440/irq.c | 1 arch/arm/mach-s3c2443/irq.c | 1 arch/arm/mach-sa1100/irq.c | 1 arch/arm/mach-sa1100/neponset.c | 1 arch/arm/mach-shark/irq.c | 1 arch/arm/mach-versatile/pci.c | 1 arch/arm/mm/alignment.c | 1 arch/arm/mm/fault.c | 5 - arch/arm/mm/init.c | 1 arch/arm/plat-omap/gpio.c | 1 arch/arm/plat-s3c24xx/irq.c | 1 arch/arm/plat-s3c24xx/s3c244x-irq.c | 1 include/asm-arm/arch-ebsa110/io.h | 8 ++ include/asm-arm/system.h | 2 38 files changed, 271 insertions(+), 151 deletions(-) diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c index fe3f059..798bbfc 100644 --- a/arch/arm/common/sa1111.c +++ b/arch/arm/common/sa1111.c @@ -18,7 +18,6 @@ #include #include #include #include -#include #include #include #include diff --git a/arch/arm/common/via82c505.c b/arch/arm/common/via82c505.c index ba2e629..79a8206 100644 --- a/arch/arm/common/via82c505.c +++ b/arch/arm/common/via82c505.c @@ -1,6 +1,5 @@ #include #include -#include #include #include #include diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c index e101846..11dcd52 100644 --- a/arch/arm/kernel/irq.c +++ b/arch/arm/kernel/irq.c @@ -27,7 +27,6 @@ #include #include #include #include -#include #include #include #include @@ -109,7 +108,7 @@ static struct irq_desc bad_irq_desc = { * come via this function. Instead, they should provide their * own 'handler' */ -asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs) +asmlinkage void __exception asm_do_IRQ(unsigned int irq, struct pt_regs *regs) { struct pt_regs *old_regs = set_irq_regs(regs); struct irq_desc *desc = irq_desc + irq; diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index 782af3c..8afd83d 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c @@ -16,7 +16,6 @@ #include #include #include #include -#include #include #include #include diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c index 9254ba2..e594b84 100644 --- a/arch/arm/kernel/ptrace.c +++ b/arch/arm/kernel/ptrace.c @@ -457,13 +457,10 @@ void ptrace_cancel_bpt(struct task_struc /* * Called by kernel/ptrace.c when detaching.. - * - * Make sure the single step bit is not set. */ void ptrace_disable(struct task_struct *child) { - child->ptrace &= ~PT_SINGLESTEP; - ptrace_cancel_bpt(child); + single_step_disable(child); } /* @@ -712,9 +709,7 @@ long arch_ptrace(struct task_struct *chi else clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); child->exit_code = data; - /* make sure single-step breakpoint is gone. */ - child->ptrace &= ~PT_SINGLESTEP; - ptrace_cancel_bpt(child); + single_step_disable(child); wake_up_process(child); ret = 0; break; @@ -725,9 +720,7 @@ long arch_ptrace(struct task_struct *chi * exit. */ case PTRACE_KILL: - /* make sure single-step breakpoint is gone. */ - child->ptrace &= ~PT_SINGLESTEP; - ptrace_cancel_bpt(child); + single_step_disable(child); if (child->exit_state != EXIT_ZOMBIE) { child->exit_code = SIGKILL; wake_up_process(child); @@ -742,7 +735,7 @@ long arch_ptrace(struct task_struct *chi ret = -EIO; if (!valid_signal(data)) break; - child->ptrace |= PT_SINGLESTEP; + single_step_enable(child); clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); child->exit_code = data; /* give it a chance to run. */ diff --git a/arch/arm/kernel/ptrace.h b/arch/arm/kernel/ptrace.h index f7cad13..def3b61 100644 --- a/arch/arm/kernel/ptrace.h +++ b/arch/arm/kernel/ptrace.h @@ -7,6 +7,45 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ +#include + extern void ptrace_cancel_bpt(struct task_struct *); extern void ptrace_set_bpt(struct task_struct *); extern void ptrace_break(struct task_struct *, struct pt_regs *); + +/* + * make sure single-step breakpoint is gone. + */ +static inline void single_step_disable(struct task_struct *task) +{ + task->ptrace &= ~PT_SINGLESTEP; + ptrace_cancel_bpt(task); +} + +static inline void single_step_enable(struct task_struct *task) +{ + task->ptrace |= PT_SINGLESTEP; +} + +/* + * Send SIGTRAP if we're single-stepping + */ +static inline void single_step_trap(struct task_struct *task) +{ + if (task->ptrace & PT_SINGLESTEP) { + ptrace_cancel_bpt(task); + send_sig(SIGTRAP, task, 1); + } +} + +static inline void single_step_clear(struct task_struct *task) +{ + if (task->ptrace & PT_SINGLESTEP) + ptrace_cancel_bpt(task); +} + +static inline void single_step_set(struct task_struct *task) +{ + if (task->ptrace & PT_SINGLESTEP) + ptrace_set_bpt(task); +} diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c index 3843d3b..54cdf1a 100644 --- a/arch/arm/kernel/signal.c +++ b/arch/arm/kernel/signal.c @@ -9,7 +9,6 @@ */ #include #include -#include #include #include @@ -285,11 +284,7 @@ asmlinkage int sys_sigreturn(struct pt_r if (restore_sigframe(regs, frame)) goto badframe; - /* Send SIGTRAP if we're single-stepping */ - if (current->ptrace & PT_SINGLESTEP) { - ptrace_cancel_bpt(current); - send_sig(SIGTRAP, current, 1); - } + single_step_trap(current); return regs->ARM_r0; @@ -324,11 +319,7 @@ asmlinkage int sys_rt_sigreturn(struct p if (do_sigaltstack(&frame->sig.uc.uc_stack, NULL, regs->ARM_sp) == -EFAULT) goto badframe; - /* Send SIGTRAP if we're single-stepping */ - if (current->ptrace & PT_SINGLESTEP) { - ptrace_cancel_bpt(current); - send_sig(SIGTRAP, current, 1); - } + single_step_trap(current); return regs->ARM_r0; @@ -644,14 +635,12 @@ static int do_signal(sigset_t *oldset, s if (try_to_freeze()) goto no_signal; - if (current->ptrace & PT_SINGLESTEP) - ptrace_cancel_bpt(current); + single_step_clear(current); signr = get_signal_to_deliver(&info, &ka, regs, NULL); if (signr > 0) { handle_signal(signr, &ka, &info, oldset, regs, syscall); - if (current->ptrace & PT_SINGLESTEP) - ptrace_set_bpt(current); + single_step_set(current); return 1; } @@ -705,8 +694,7 @@ #endif restart_syscall(regs); } } - if (current->ptrace & PT_SINGLESTEP) - ptrace_set_bpt(current); + single_step_set(current); return 0; } diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index 2409560..6055ab4 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c @@ -16,7 +16,6 @@ #include #include #include #include -#include #include #include #include @@ -45,7 +44,18 @@ static int __init user_debug_setup(char __setup("user_debug=", user_debug_setup); #endif -void dump_backtrace_entry(unsigned long where, unsigned long from) +static void dump_mem(const char *str, unsigned long bottom, unsigned long top); + +static inline int in_exception_text(unsigned long ptr) +{ + extern char __exception_text_start[]; + extern char __exception_text_end[]; + + return ptr >= (unsigned long)&__exception_text_start && + ptr < (unsigned long)&__exception_text_end; +} + +void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame) { #ifdef CONFIG_KALLSYMS printk("[<%08lx>] ", where); @@ -55,6 +65,9 @@ #ifdef CONFIG_KALLSYMS #else printk("Function entered at [<%08lx>] from [<%08lx>]\n", where, from); #endif + + if (in_exception_text(where)) + dump_mem("Exception stack", frame + 4, frame + 4 + sizeof(struct pt_regs)); } /* @@ -266,7 +279,7 @@ void unregister_undef_hook(struct undef_ spin_unlock_irqrestore(&undef_lock, flags); } -asmlinkage void do_undefinstr(struct pt_regs *regs) +asmlinkage void __exception do_undefinstr(struct pt_regs *regs) { unsigned int correction = thumb_mode(regs) ? 2 : 4; unsigned int instr; diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S index ddbdad4..b295f6a 100644 --- a/arch/arm/kernel/vmlinux.lds.S +++ b/arch/arm/kernel/vmlinux.lds.S @@ -83,6 +83,9 @@ #endif .text : { /* Real text segment */ _text = .; /* Text and read-only data */ + __exception_text_start = .; + *(.exception.text) + __exception_text_end = .; *(.text) SCHED_TEXT LOCK_TEXT diff --git a/arch/arm/lib/backtrace.S b/arch/arm/lib/backtrace.S index 7423008..84dc890 100644 --- a/arch/arm/lib/backtrace.S +++ b/arch/arm/lib/backtrace.S @@ -17,8 +17,8 @@ #include @ fp is 0 or stack frame #define frame r4 -#define next r5 -#define save r6 +#define sv_fp r5 +#define sv_pc r6 #define mask r7 #define offset r8 @@ -31,108 +31,106 @@ ENTRY(c_backtrace) #if !defined(CONFIG_FRAME_POINTER) || !defined(CONFIG_PRINTK) mov pc, lr #else - stmfd sp!, {r4 - r8, lr} @ Save an extra register so we have a location... - tst r1, #0x10 @ 26 or 32-bit? - moveq mask, #0xfc000003 - movne mask, #0 - tst mask, r0 - movne r0, #0 - movs frame, r0 -1: moveq r0, #-2 - ldmeqfd sp!, {r4 - r8, pc} - -2: stmfd sp!, {pc} @ calculate offset of PC in STMIA instruction - ldr r0, [sp], #4 - adr r1, 2b - 4 + movs frame, r0 @ if frame pointer is zero + beq no_frame @ we have no stack frames + + tst r1, #0x10 @ 26 or 32-bit mode? + moveq mask, #0xfc000003 @ mask for 26-bit + movne mask, #0 @ mask for 32-bit + +1: stmfd sp!, {pc} @ calculate offset of PC stored + ldr r0, [sp], #4 @ by stmfd for this CPU + adr r1, 1b sub offset, r0, r1 -3: tst frame, mask @ Check for address exceptions... - bne 1b +/* + * Stack frame layout: + * optionally saved caller registers (r4 - r10) + * saved fp + * saved sp + * saved lr + * frame => saved pc + * optionally saved arguments (r0 - r3) + * saved sp => + * + * Functions start with the following code sequence: + * mov ip, sp + * stmfd sp!, {r0 - r3} (optional) + * corrected pc => stmfd sp!, {..., fp, ip, lr, pc} + */ +for_each_frame: tst frame, mask @ Check for address exceptions + bne no_frame + +1001: ldr sv_pc, [frame, #0] @ get saved pc +1002: ldr sv_fp, [frame, #-12] @ get saved fp -1001: ldr next, [frame, #-12] @ get fp -1002: ldr r2, [frame, #-4] @ get lr -1003: ldr r3, [frame, #0] @ get pc - sub save, r3, offset @ Correct PC for prefetching - bic save, save, mask -1004: ldr r1, [save, #0] @ get instruction at function - mov r1, r1, lsr #10 - ldr r3, .Ldsi+4 - teq r1, r3 - subeq save, save, #4 - mov r0, save - bic r1, r2, mask + sub sv_pc, sv_pc, offset @ Correct PC for prefetching + bic sv_pc, sv_pc, mask @ mask PC/LR for the mode + +1003: ldr r2, [sv_pc, #-4] @ if stmfd sp!, {args} exists, + ldr r3, .Ldsi+4 @ adjust saved 'pc' back one + teq r3, r2, lsr #10 @ instruction + subne r0, sv_pc, #4 @ allow for mov + subeq r0, sv_pc, #8 @ allow for mov + stmia + + ldr r1, [frame, #-4] @ get saved lr + mov r2, frame + bic r1, r1, mask @ mask PC/LR for the mode bl dump_backtrace_entry - ldr r0, [frame, #-8] @ get sp - sub r0, r0, #4 -1005: ldr r1, [save, #4] @ get instruction at function+4 - mov r3, r1, lsr #10 - ldr r2, .Ldsi+4 - teq r3, r2 @ Check for stmia sp!, {args} - addeq save, save, #4 @ next instruction - bleq .Ldumpstm - - sub r0, frame, #16 -1006: ldr r1, [save, #4] @ Get 'stmia sp!, {rlist, fp, ip, lr, pc}' instruction - mov r3, r1, lsr #10 - ldr r2, .Ldsi - teq r3, r2 - bleq .Ldumpstm - - /* - * A zero next framepointer means we're done. - */ - teq next, #0 - ldmeqfd sp!, {r4 - r8, pc} - - /* - * The next framepointer must be above the - * current framepointer. - */ - cmp next, frame - mov frame, next - bhi 3b - b 1007f + ldr r1, [sv_pc, #-4] @ if stmfd sp!, {args} exists, + ldr r3, .Ldsi+4 + teq r3, r1, lsr #10 + ldreq r0, [frame, #-8] @ get sp + subeq r0, r0, #4 @ point at the last arg + bleq .Ldumpstm @ dump saved registers -/* - * Fixup for LDMDB. Note that this must not be in the fixup section. - */ -1007: ldr r0, =.Lbad +1004: ldr r1, [sv_pc, #0] @ if stmfd sp!, {..., fp, ip, lr, pc} + ldr r3, .Ldsi @ instruction exists, + teq r3, r1, lsr #10 + subeq r0, frame, #16 + bleq .Ldumpstm @ dump saved registers + + teq sv_fp, #0 @ zero saved fp means + beq no_frame @ no further frames + + cmp sv_fp, frame @ next frame must be + mov frame, sv_fp @ above the current frame + bhi for_each_frame + +1006: adr r0, .Lbad mov r1, frame bl printk - ldmfd sp!, {r4 - r8, pc} - .ltorg +no_frame: ldmfd sp!, {r4 - r8, pc} .section __ex_table,"a" .align 3 - .long 1001b, 1007b - .long 1002b, 1007b - .long 1003b, 1007b - .long 1004b, 1007b - .long 1005b, 1007b - .long 1006b, 1007b + .long 1001b, 1006b + .long 1002b, 1006b + .long 1003b, 1006b + .long 1004b, 1006b .previous #define instr r4 #define reg r5 #define stack r6 -.Ldumpstm: stmfd sp!, {instr, reg, stack, r7, r8, lr} +.Ldumpstm: stmfd sp!, {instr, reg, stack, r7, lr} mov stack, r0 mov instr, r1 - mov reg, #9 + mov reg, #10 mov r7, #0 1: mov r3, #1 tst instr, r3, lsl reg beq 2f add r7, r7, #1 - teq r7, #4 - moveq r7, #0 - moveq r3, #'\n' - movne r3, #' ' - ldr r2, [stack], #-4 - mov r1, reg + teq r7, #6 + moveq r7, #1 + moveq r1, #'\n' + movne r1, #' ' + ldr r3, [stack], #-4 + mov r2, reg adr r0, .Lfp bl printk 2: subs reg, reg, #1 @@ -140,14 +138,13 @@ #define stack r6 teq r7, #0 adrne r0, .Lcr blne printk - mov r0, stack - ldmfd sp!, {instr, reg, stack, r7, r8, pc} + ldmfd sp!, {instr, reg, stack, r7, pc} -.Lfp: .asciz " r%d = %08X%c" +.Lfp: .asciz "%cr%d:%08x" .Lcr: .asciz "\n" .Lbad: .asciz "Backtrace aborted due to bad frame pointer <%p>\n" .align -.Ldsi: .word 0x00e92dd8 >> 2 - .word 0x00e92d00 >> 2 +.Ldsi: .word 0xe92dd800 >> 10 @ stmfd sp!, {... fp, ip, lr, pc} + .word 0xe92d0000 >> 10 @ stmfd sp!, {} #endif diff --git a/arch/arm/lib/getuser.S b/arch/arm/lib/getuser.S index c03ea8e..1dd8ea4 100644 --- a/arch/arm/lib/getuser.S +++ b/arch/arm/lib/getuser.S @@ -26,8 +26,6 @@ * Note that ADDR_LIMIT is either 0 or 0xc0000000. * Note also that it is intended that __get_user_bad is not global. */ -#include -#include #include .global __get_user_1 diff --git a/arch/arm/lib/putuser.S b/arch/arm/lib/putuser.S index 4593e9c..8620afe 100644 --- a/arch/arm/lib/putuser.S +++ b/arch/arm/lib/putuser.S @@ -26,8 +26,6 @@ * Note that ADDR_LIMIT is either 0 or 0xc0000000 * Note also that it is intended that __put_user_bad is not global. */ -#include -#include #include .global __put_user_1 diff --git a/arch/arm/mach-ebsa110/io.c b/arch/arm/mach-ebsa110/io.c index db38afb..bbf0d33 100644 --- a/arch/arm/mach-ebsa110/io.c +++ b/arch/arm/mach-ebsa110/io.c @@ -102,6 +102,26 @@ EXPORT_SYMBOL(__readb); EXPORT_SYMBOL(__readw); EXPORT_SYMBOL(__readl); +void readsw(void __iomem *addr, void *data, int len) +{ + void __iomem *a = __isamem_convert_addr(addr); + + BUG_ON((unsigned long)addr & 1); + + __raw_readsw(a, data, len); +} +EXPORT_SYMBOL(readsw); + +void readsl(void __iomem *addr, void *data, int len) +{ + void __iomem *a = __isamem_convert_addr(addr); + + BUG_ON((unsigned long)addr & 3); + + __raw_readsl(a, data, len); +} +EXPORT_SYMBOL(readsl); + void __writeb(u8 val, void __iomem *addr) { void __iomem *a = __isamem_convert_addr(addr); @@ -137,6 +157,26 @@ EXPORT_SYMBOL(__writeb); EXPORT_SYMBOL(__writew); EXPORT_SYMBOL(__writel); +void writesw(void __iomem *addr, void *data, int len) +{ + void __iomem *a = __isamem_convert_addr(addr); + + BUG_ON((unsigned long)addr & 1); + + __raw_writesw(a, data, len); +} +EXPORT_SYMBOL(writesw); + +void writesl(void __iomem *addr, void *data, int len) +{ + void __iomem *a = __isamem_convert_addr(addr); + + BUG_ON((unsigned long)addr & 3); + + __raw_writesl(a, data, len); +} +EXPORT_SYMBOL(writesl); + #define SUPERIO_PORT(p) \ (((p) >> 3) == (0x3f8 >> 3) || \ ((p) >> 3) == (0x2f8 >> 3) || \ diff --git a/arch/arm/mach-footbridge/dc21285.c b/arch/arm/mach-footbridge/dc21285.c index 1463330..d0dc51e 100644 --- a/arch/arm/mach-footbridge/dc21285.c +++ b/arch/arm/mach-footbridge/dc21285.c @@ -10,7 +10,6 @@ */ #include #include -#include #include #include #include diff --git a/arch/arm/mach-integrator/pci.c b/arch/arm/mach-integrator/pci.c index 394ec92..af7d3ff 100644 --- a/arch/arm/mach-integrator/pci.c +++ b/arch/arm/mach-integrator/pci.c @@ -23,7 +23,6 @@ */ #include #include -#include #include #include diff --git a/arch/arm/mach-integrator/pci_v3.c b/arch/arm/mach-integrator/pci_v3.c index fb8c6d9..af9ebcc 100644 --- a/arch/arm/mach-integrator/pci_v3.c +++ b/arch/arm/mach-integrator/pci_v3.c @@ -22,7 +22,6 @@ */ #include #include -#include #include #include #include diff --git a/arch/arm/mach-lh7a40x/irq-lh7a400.c b/arch/arm/mach-lh7a40x/irq-lh7a400.c index 0b938e8..9472bbe 100644 --- a/arch/arm/mach-lh7a40x/irq-lh7a400.c +++ b/arch/arm/mach-lh7a40x/irq-lh7a400.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include diff --git a/arch/arm/mach-lh7a40x/irq-lh7a404.c b/arch/arm/mach-lh7a40x/irq-lh7a404.c index 5760f8c..9b28389 100644 --- a/arch/arm/mach-lh7a40x/irq-lh7a404.c +++ b/arch/arm/mach-lh7a40x/irq-lh7a404.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include diff --git a/arch/arm/mach-lh7a40x/irq-lpd7a40x.c b/arch/arm/mach-lh7a40x/irq-lpd7a40x.c index 15b9577..66e1ed3 100644 --- a/arch/arm/mach-lh7a40x/irq-lpd7a40x.c +++ b/arch/arm/mach-lh7a40x/irq-lpd7a40x.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include diff --git a/arch/arm/mach-omap1/irq.c b/arch/arm/mach-omap1/irq.c index 410d3e7..0733078 100644 --- a/arch/arm/mach-omap1/irq.c +++ b/arch/arm/mach-omap1/irq.c @@ -40,7 +40,6 @@ #include #include #include #include -#include #include #include diff --git a/arch/arm/mach-pxa/irq.c b/arch/arm/mach-pxa/irq.c index f815678..4619d5f 100644 --- a/arch/arm/mach-pxa/irq.c +++ b/arch/arm/mach-pxa/irq.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include @@ -39,11 +38,33 @@ static void pxa_unmask_low_irq(unsigned ICMR |= (1 << (irq + PXA_IRQ_SKIP)); } +static int pxa_set_wake(unsigned int irq, unsigned int on) +{ + u32 mask; + + switch (irq) { + case IRQ_RTCAlrm: + mask = PWER_RTC; + break; +#ifdef CONFIG_PXA27x + /* REVISIT can handle USBH1, USBH2, USB, MSL, USIM, ... */ +#endif + default: + return -EINVAL; + } + if (on) + PWER |= mask; + else + PWER &= ~mask; + return 0; +} + static struct irq_chip pxa_internal_chip_low = { .name = "SC", .ack = pxa_mask_low_irq, .mask = pxa_mask_low_irq, .unmask = pxa_unmask_low_irq, + .set_wake = pxa_set_wake, }; #if PXA_INTERNAL_IRQS > 32 @@ -71,6 +92,26 @@ static struct irq_chip pxa_internal_chip #endif +/* Note that if an input/irq line ever gets changed to an output during + * suspend, the relevant PWER, PRER, and PFER bits should be cleared. + */ +#ifdef CONFIG_PXA27x + +/* PXA27x: Various gpios can issue wakeup events. This logic only + * handles the simple cases, not the WEMUX2 and WEMUX3 options + */ +#define PXA27x_GPIO_NOWAKE_MASK \ + ((1 << 8) | (1 << 7) | (1 << 6) | (1 << 5) | (1 << 2)) +#define WAKEMASK(gpio) \ + (((gpio) <= 15) \ + ? ((1 << (gpio)) & ~PXA27x_GPIO_NOWAKE_MASK) \ + : ((gpio == 35) ? (1 << 24) : 0)) +#else + +/* pxa 210, 250, 255, 26x: gpios 0..15 can issue wakeups */ +#define WAKEMASK(gpio) (((gpio) <= 15) ? (1 << (gpio)) : 0) +#endif + /* * PXA GPIO edge detection for IRQs: * IRQs are generated on Falling-Edge, Rising-Edge, or both. @@ -84,9 +125,11 @@ static long GPIO_IRQ_mask[4]; static int pxa_gpio_irq_type(unsigned int irq, unsigned int type) { int gpio, idx; + u32 mask; gpio = IRQ_TO_GPIO(irq); idx = gpio >> 5; + mask = WAKEMASK(gpio); if (type == IRQT_PROBE) { /* Don't mess with enabled GPIOs using preconfigured edges or @@ -106,14 +149,20 @@ static int pxa_gpio_irq_type(unsigned in if (type & __IRQT_RISEDGE) { /* printk("rising "); */ __set_bit (gpio, GPIO_IRQ_rising_edge); - } else + PRER |= mask; + } else { __clear_bit (gpio, GPIO_IRQ_rising_edge); + PRER &= ~mask; + } if (type & __IRQT_FALEDGE) { /* printk("falling "); */ __set_bit (gpio, GPIO_IRQ_falling_edge); - } else + PFER |= mask; + } else { __clear_bit (gpio, GPIO_IRQ_falling_edge); + PFER &= ~mask; + } /* printk("edges\n"); */ @@ -131,12 +180,29 @@ static void pxa_ack_low_gpio(unsigned in GEDR0 = (1 << (irq - IRQ_GPIO0)); } +static int pxa_set_gpio_wake(unsigned int irq, unsigned int on) +{ + int gpio = IRQ_TO_GPIO(irq); + u32 mask = WAKEMASK(gpio); + + if (!mask) + return -EINVAL; + + if (on) + PWER |= mask; + else + PWER &= ~mask; + return 0; +} + + static struct irq_chip pxa_low_gpio_chip = { .name = "GPIO-l", .ack = pxa_ack_low_gpio, .mask = pxa_mask_low_irq, .unmask = pxa_unmask_low_irq, .set_type = pxa_gpio_irq_type, + .set_wake = pxa_set_gpio_wake, }; /* @@ -245,6 +311,7 @@ static struct irq_chip pxa_muxed_gpio_ch .mask = pxa_mask_muxed_gpio, .unmask = pxa_unmask_muxed_gpio, .set_type = pxa_gpio_irq_type, + .set_wake = pxa_set_gpio_wake, }; diff --git a/arch/arm/mach-s3c2410/bast-irq.c b/arch/arm/mach-s3c2410/bast-irq.c index daeba42..76a7cb1 100644 --- a/arch/arm/mach-s3c2410/bast-irq.c +++ b/arch/arm/mach-s3c2410/bast-irq.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include diff --git a/arch/arm/mach-s3c2410/irq.c b/arch/arm/mach-s3c2410/irq.c index 53cbdaa..f5c5c53 100644 --- a/arch/arm/mach-s3c2410/irq.c +++ b/arch/arm/mach-s3c2410/irq.c @@ -23,7 +23,6 @@ #include #include #include #include -#include #include #include diff --git a/arch/arm/mach-s3c2412/irq.c b/arch/arm/mach-s3c2412/irq.c index e89dbdc..f0d6682 100644 --- a/arch/arm/mach-s3c2412/irq.c +++ b/arch/arm/mach-s3c2412/irq.c @@ -23,7 +23,6 @@ #include #include #include #include -#include #include #include diff --git a/arch/arm/mach-s3c2440/irq.c b/arch/arm/mach-s3c2440/irq.c index 1069d13..a87608b 100644 --- a/arch/arm/mach-s3c2440/irq.c +++ b/arch/arm/mach-s3c2440/irq.c @@ -23,7 +23,6 @@ #include #include #include #include -#include #include #include diff --git a/arch/arm/mach-s3c2443/irq.c b/arch/arm/mach-s3c2443/irq.c index 7a45b6d..a5dea6d 100644 --- a/arch/arm/mach-s3c2443/irq.c +++ b/arch/arm/mach-s3c2443/irq.c @@ -23,7 +23,6 @@ #include #include #include #include -#include #include #include diff --git a/arch/arm/mach-sa1100/irq.c b/arch/arm/mach-sa1100/irq.c index 5642aec..edf3347 100644 --- a/arch/arm/mach-sa1100/irq.c +++ b/arch/arm/mach-sa1100/irq.c @@ -14,7 +14,6 @@ #include #include #include #include -#include #include #include diff --git a/arch/arm/mach-sa1100/neponset.c b/arch/arm/mach-sa1100/neponset.c index 075d4d1..d7c038a 100644 --- a/arch/arm/mach-sa1100/neponset.c +++ b/arch/arm/mach-sa1100/neponset.c @@ -4,7 +4,6 @@ */ #include #include -#include #include #include #include diff --git a/arch/arm/mach-shark/irq.c b/arch/arm/mach-shark/irq.c index 00a6c14..5b0c6af 100644 --- a/arch/arm/mach-shark/irq.c +++ b/arch/arm/mach-shark/irq.c @@ -10,7 +10,6 @@ #include #include -#include #include #include diff --git a/arch/arm/mach-versatile/pci.c b/arch/arm/mach-versatile/pci.c index 5cd0b5d..ba58223 100644 --- a/arch/arm/mach-versatile/pci.c +++ b/arch/arm/mach-versatile/pci.c @@ -16,7 +16,6 @@ */ #include #include -#include #include #include #include diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c index aa109f0..19ca333 100644 --- a/arch/arm/mm/alignment.c +++ b/arch/arm/mm/alignment.c @@ -15,7 +15,6 @@ #include #include #include #include -#include #include #include diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c index 9fd6d2e..5d9ce7d 100644 --- a/arch/arm/mm/fault.c +++ b/arch/arm/mm/fault.c @@ -10,7 +10,6 @@ */ #include #include -#include #include #include @@ -438,7 +437,7 @@ hook_fault_code(int nr, int (*fn)(unsign /* * Dispatch a data abort to the relevant handler. */ -asmlinkage void +asmlinkage void __exception do_DataAbort(unsigned long addr, unsigned int fsr, struct pt_regs *regs) { const struct fsr_info *inf = fsr_info + (fsr & 15) + ((fsr & (1 << 10)) >> 6); @@ -457,7 +456,7 @@ do_DataAbort(unsigned long addr, unsigne notify_die("", regs, &info, fsr, 0); } -asmlinkage void +asmlinkage void __exception do_PrefetchAbort(unsigned long addr, struct pt_regs *regs) { do_translation_fault(addr, 0, regs); diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index 7760193..c0ad7c0 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -9,7 +9,6 @@ */ #include #include -#include #include #include #include diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c index b8c01de..8bedc8f 100644 --- a/arch/arm/plat-omap/gpio.c +++ b/arch/arm/plat-omap/gpio.c @@ -15,7 +15,6 @@ #include #include #include #include -#include #include #include #include diff --git a/arch/arm/plat-s3c24xx/irq.c b/arch/arm/plat-s3c24xx/irq.c index ce18639..8fbc884 100644 --- a/arch/arm/plat-s3c24xx/irq.c +++ b/arch/arm/plat-s3c24xx/irq.c @@ -54,7 +54,6 @@ #include #include #include #include -#include #include #include diff --git a/arch/arm/plat-s3c24xx/s3c244x-irq.c b/arch/arm/plat-s3c24xx/s3c244x-irq.c index a0e39d8..2dbb260 100644 --- a/arch/arm/plat-s3c24xx/s3c244x-irq.c +++ b/arch/arm/plat-s3c24xx/s3c244x-irq.c @@ -23,7 +23,6 @@ #include #include #include #include -#include #include #include diff --git a/include/asm-arm/arch-ebsa110/io.h b/include/asm-arm/arch-ebsa110/io.h index 722c5e0..44a4001 100644 --- a/include/asm-arm/arch-ebsa110/io.h +++ b/include/asm-arm/arch-ebsa110/io.h @@ -81,4 +81,12 @@ extern void outsb(unsigned int port, con extern void outsw(unsigned int port, const void *buf, int sz); extern void outsl(unsigned int port, const void *buf, int sz); +/* can't support writesb atm */ +extern void writesw(void __iomem *addr, const void *data, int wordlen); +extern void writesl(void __iomem *addr, const void *data, int longlen); + +/* can't support readsb atm */ +extern void readsw(const void __iomem *addr, void *data, int wordlen); +extern void readsl(const void __iomem *addr, void *data, int longlen); + #endif diff --git a/include/asm-arm/system.h b/include/asm-arm/system.h index f06d8a4..af8a840 100644 --- a/include/asm-arm/system.h +++ b/include/asm-arm/system.h @@ -75,6 +75,8 @@ #ifndef __ASSEMBLY__ #include #include +#define __exception __attribute__((section(".exception.text"))) + struct thread_info; struct task_struct;