diff options
| author | Linus Torvalds <torvalds@home.transmeta.com> | 2002-07-27 06:30:08 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@home.transmeta.com> | 2002-07-27 06:30:08 -0700 |
| commit | d45db7c22033a7042cabab3cd2f2d72ac53e69b2 (patch) | |
| tree | 0ad8dd14702943aa50bd287142918eb12cfb617c | |
| parent | ddef8ca8d041eb43a20ead6ae500a5e84aa847f3 (diff) | |
| parent | 13243cc58d33a0db19ca8e846fdb66e5ad527e1f (diff) | |
Merge bk://bkbits.ras.ucalgary.ca/rgooch-2.5
into home.transmeta.com:/home/torvalds/v2.5/linux
57 files changed, 902 insertions, 725 deletions
diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S index d4e28cbe3531..04a43eb5c256 100644 --- a/arch/arm/kernel/calls.S +++ b/arch/arm/kernel/calls.S @@ -237,7 +237,7 @@ __syscall_start: /* 220 */ .long sys_madvise .long sys_fcntl64 .long sys_ni_syscall /* TUX */ - .long sys_ni_syscall /* Security */ + .long sys_security .long sys_gettid /* 225 */ .long sys_readahead .long sys_setxattr diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index 0cd3e7e6b8b9..eafe01fbf06f 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S @@ -725,7 +725,7 @@ __dabt_svc: sub sp, sp, #S_FRAME_SIZE msr cpsr_c, r9 mov r2, sp bl do_DataAbort - set_cpsr_c r0, #PSR_I_BIT | MODE_SVC + disable_irq r0 ldr r0, [sp, #S_PSR] msr spsr, r0 ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr @@ -776,9 +776,9 @@ svc_preempt: teq r9, #0 @ was preempt count = 0 movne pc, lr mov r7, #PREEMPT_ACTIVE str r7, [r8, #TI_PREEMPT] @ set PREEMPT_ACTIVE -1: set_cpsr_c r2, #MODE_SVC @ enable IRQs +1: enable_irq r2 @ enable IRQs bl schedule - set_cpsr_c r0, #PSR_I_BIT | MODE_SVC @ disable IRQs + disable_irq r0 @ disable IRQs ldr r0, [r8, #TI_FLAGS] @ get new tasks TI_FLAGS tst r0, #_TIF_NEED_RESCHED beq preempt_return @ go again @@ -801,7 +801,7 @@ __und_svc: sub sp, sp, #S_FRAME_SIZE mov r0, sp @ struct pt_regs *regs bl do_undefinstr -1: set_cpsr_c r0, #PSR_I_BIT | MODE_SVC +1: disable_irq r0 ldr lr, [sp, #S_PSR] @ Get SVC cpsr msr spsr, lr ldmia sp, {r0 - pc}^ @ Restore SVC registers @@ -822,7 +822,7 @@ __pabt_svc: sub sp, sp, #S_FRAME_SIZE mov r0, r2 @ address (pc) mov r1, sp @ regs bl do_PrefetchAbort @ call abort handler - set_cpsr_c r0, #PSR_I_BIT | MODE_SVC + disable_irq r0 ldr r0, [sp, #S_PSR] msr spsr, r0 ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr @@ -861,7 +861,7 @@ __dabt_usr: sub sp, sp, #S_FRAME_SIZE @ Allocate frame size in one go #else bl CPU_ABORT_HANDLER #endif - set_cpsr_c r2, #MODE_SVC @ Enable interrupts + enable_irq r2 @ Enable interrupts mov r2, sp adrsvc al, lr, ret_from_exception b do_DataAbort @@ -916,7 +916,7 @@ __und_usr: sub sp, sp, #S_FRAME_SIZE @ Allocate frame size in one go adrsvc al, r9, ret_from_exception @ r9 = normal FP return adrsvc al, lr, fpundefinstr @ lr = undefined instr return -call_fpe: set_cpsr_c r0, #MODE_SVC @ Enable interrupts +call_fpe: enable_irq r0 @ Enable interrupts get_thread_info r10 @ get current thread ldr r4, [r10, #TI_TASK] @ get current task mov r8, #1 @@ -939,7 +939,7 @@ __pabt_usr: sub sp, sp, #S_FRAME_SIZE @ Allocate frame size in one go stmdb r8, {sp, lr}^ @ Save sp_usr lr_usr alignment_trap r4, r7, __temp_abt zero_fp - set_cpsr_c r0, #MODE_SVC @ Enable interrupts + enable_irq r0 @ Enable interrupts mov r0, r5 @ address (pc) mov r1, sp @ regs bl do_PrefetchAbort @ call abort handler diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S index 81c6ea1ef83c..d4f1cedd4d92 100644 --- a/arch/arm/kernel/entry-common.S +++ b/arch/arm/kernel/entry-common.S @@ -35,18 +35,27 @@ ENTRY(__do_softirq) * stack. */ ret_fast_syscall: - set_cpsr_c r1, #PSR_I_BIT | MODE_SVC @ disable interrupts + disable_irq r1 @ disable interrupts ldr r1, [tsk, #TI_FLAGS] tst r1, #_TIF_WORK_MASK - bne ret_fast_work + bne fast_work_pending fast_restore_user_regs /* * Ok, we need to do extra processing, enter the slow path. */ -ret_fast_work: - str r0, [sp, #S_R0+S_OFF]! @ returned r0 - b work_pending +fast_work_pending: + str r0, [sp, #S_R0+S_OFF]! @ returned r0 +work_pending: + tst r1, #_TIF_NEED_RESCHED + bne work_resched + tst r1, #_TIF_NOTIFY_RESUME | _TIF_SIGPENDING + beq no_work_pending + mov r0, sp @ 'regs' + mov r2, why @ 'syscall' + bl do_notify_resume + disable_irq r1 @ disable interrupts + b no_work_pending work_resched: bl schedule @@ -55,22 +64,12 @@ work_resched: */ ENTRY(ret_to_user) ret_slow_syscall: - set_cpsr_c r1, #PSR_I_BIT | MODE_SVC @ disable interrupts + disable_irq r1 @ disable interrupts ldr r1, [tsk, #TI_FLAGS] tst r1, #_TIF_WORK_MASK - beq no_work_pending -work_pending: - tst r1, #_TIF_NEED_RESCHED - bne work_resched - tst r1, #_TIF_NOTIFY_RESUME | _TIF_SIGPENDING - blne __do_notify_resume + bne work_pending no_work_pending: - restore_user_regs - -__do_notify_resume: - mov r0, sp @ 'regs' - mov r2, why @ 'syscall' - b do_notify_resume @ note the bl above sets lr + slow_restore_user_regs /* * This is how we return from a fork. @@ -80,9 +79,9 @@ ENTRY(ret_from_fork) bl schedule_tail #endif get_thread_info tsk - ldr ip, [tsk, #TI_FLAGS] @ check for syscall tracing + ldr r1, [tsk, #TI_FLAGS] @ check for syscall tracing mov why, #1 - tst ip, #_TIF_SYSCALL_TRACE @ are we tracing syscalls? + tst r1, #_TIF_SYSCALL_TRACE @ are we tracing syscalls? beq ret_slow_syscall mov r1, sp mov r0, #1 @ trace exit [IP = 1] @@ -134,7 +133,7 @@ ENTRY(vector_swi) ldr ip, [ip] mcr p15, 0, ip, c1, c0 @ update control register #endif - enable_irqs ip + enable_irq ip str r4, [sp, #-S_OFF]! @ push fifth arg diff --git a/arch/arm/kernel/entry-header.S b/arch/arm/kernel/entry-header.S index f82c11287e0e..7a0f8f379ec1 100644 --- a/arch/arm/kernel/entry-header.S +++ b/arch/arm/kernel/entry-header.S @@ -11,13 +11,13 @@ #define MODE_SVC 0x13 #endif - .macro zero_fp + .macro zero_fp #ifndef CONFIG_NO_FRAME_POINTER - mov fp, #0 + mov fp, #0 #endif - .endm + .endm - .text + .text @ Bad Abort numbers @ ----------------- @@ -69,119 +69,146 @@ #define S_OFF 8 #ifdef CONFIG_CPU_32 - .macro save_user_regs - sub sp, sp, #S_FRAME_SIZE - stmia sp, {r0 - r12} @ Calling r0 - r12 - add r8, sp, #S_PC - stmdb r8, {sp, lr}^ @ Calling sp, lr - mrs r8, spsr @ called from non-FIQ mode, so ok. - str lr, [sp, #S_PC] @ Save calling PC - str r8, [sp, #S_PSR] @ Save CPSR - str r0, [sp, #S_OLD_R0] @ Save OLD_R0 - .endm - - .macro restore_user_regs - ldr r0, [sp, #S_PSR] @ Get calling cpsr - mov ip, #PSR_I_BIT | MODE_SVC - msr cpsr_c, ip @ disable IRQs - msr spsr, r0 @ save in spsr_svc - ldr lr, [sp, #S_PC] @ Get PC - ldmia sp, {r0 - lr}^ @ Get calling r0 - lr - mov r0, r0 - add sp, sp, #S_FRAME_SIZE - movs pc, lr @ return & move spsr_svc into cpsr - .endm - - .macro fast_restore_user_regs - mov ip, #PSR_I_BIT | MODE_SVC - msr cpsr_c, ip @ disable IRQs - ldr r1, [sp, #S_OFF + S_PSR] @ get calling cpsr - ldr lr, [sp, #S_OFF + S_PC]! @ get pc - msr spsr, r1 @ save in spsr_svc - ldmdb sp, {r1 - lr}^ @ get calling r1 - lr - mov r0, r0 - add sp, sp, #S_FRAME_SIZE - S_PC - movs pc, lr @ return & move spsr_svc into cpsr - .endm - - .macro mask_pc, rd, rm - .endm - - .macro enable_irqs, temp - mov \temp, #MODE_SVC - msr cpsr_c, \temp - .endm - - .macro get_thread_info, rd - mov \rd, sp, lsr #13 - mov \rd, \rd, lsl #13 - .endm - - /* - * Like adr, but force SVC mode (if required) - */ - .macro adrsvc, cond, reg, label - adr\cond \reg, \label - .endm - - .macro alignment_trap, rbase, rtemp, sym + + .macro set_cpsr_c, reg, mode +#if 1 + /* broken binutils */ + mov \reg, \mode + msr cpsr_c, \reg +#else + msr cpsr_c, \mode +#endif + .endm + + .macro disable_irq, temp + set_cpsr_c \temp, #PSR_I_BIT | MODE_SVC + .endm + + .macro enable_irq, temp + set_cpsr_c \temp, #MODE_SVC + .endm + + .macro save_user_regs + sub sp, sp, #S_FRAME_SIZE + stmia sp, {r0 - r12} @ Calling r0 - r12 + add r8, sp, #S_PC + stmdb r8, {sp, lr}^ @ Calling sp, lr + mrs r8, spsr @ called from non-FIQ mode, so ok. + str lr, [sp, #S_PC] @ Save calling PC + str r8, [sp, #S_PSR] @ Save CPSR + str r0, [sp, #S_OLD_R0] @ Save OLD_R0 + .endm + + .macro restore_user_regs + ldr r1, [sp, #S_PSR] @ Get calling cpsr + disable_irq ip @ disable IRQs + ldr lr, [sp, #S_PC]! @ Get PC + msr spsr, r1 @ save in spsr_svc + ldmdb sp, {r0 - lr}^ @ Get calling r0 - lr + mov r0, r0 + add sp, sp, #S_FRAME_SIZE - S_PC + movs pc, lr @ return & move spsr_svc into cpsr + .endm + +/* + * Must be called with IRQs already disabled. + */ + .macro fast_restore_user_regs + ldr r1, [sp, #S_OFF + S_PSR] @ get calling cpsr + ldr lr, [sp, #S_OFF + S_PC]! @ get pc + msr spsr, r1 @ save in spsr_svc + ldmdb sp, {r1 - lr}^ @ get calling r1 - lr + mov r0, r0 + add sp, sp, #S_FRAME_SIZE - S_PC + movs pc, lr @ return & move spsr_svc into cpsr + .endm + +/* + * Must be called with IRQs already disabled. + */ + .macro slow_restore_user_regs + ldr r1, [sp, #S_PSR] @ get calling cpsr + ldr lr, [sp, #S_PC]! @ get pc + msr spsr, r1 @ save in spsr_svc + ldmdb sp, {r0 - lr}^ @ get calling r1 - lr + mov r0, r0 + add sp, sp, #S_FRAME_SIZE - S_PC + movs pc, lr @ return & move spsr_svc into cpsr + .endm + + .macro mask_pc, rd, rm + .endm + + .macro get_thread_info, rd + mov \rd, sp, lsr #13 + mov \rd, \rd, lsl #13 + .endm + +/* + * Like adr, but force SVC mode (if required) + */ + .macro adrsvc, cond, reg, label + adr\cond \reg, \label + .endm + + .macro alignment_trap, rbase, rtemp, sym #ifdef CONFIG_ALIGNMENT_TRAP #define OFF_CR_ALIGNMENT(x) cr_alignment - x - ldr \rtemp, [\rbase, #OFF_CR_ALIGNMENT(\sym)] - mcr p15, 0, \rtemp, c1, c0 + ldr \rtemp, [\rbase, #OFF_CR_ALIGNMENT(\sym)] + mcr p15, 0, \rtemp, c1, c0 #endif - .endm + .endm #else - .macro save_user_regs - str r0, [sp, #-4]! - str lr, [sp, #-4]! - sub sp, sp, #15*4 - stmia sp, {r0 - lr}^ - mov r0, r0 - .endm - - .macro restore_user_regs - ldmia sp, {r0 - lr}^ - mov r0, r0 - ldr lr, [sp, #15*4] - add sp, sp, #15*4+8 - movs pc, lr - .endm - - .macro fast_restore_user_regs - add sp, sp, #S_OFF - ldmib sp, {r1 - lr}^ - mov r0, r0 - ldr lr, [sp, #15*4] - add sp, sp, #15*4+8 - movs pc, lr - .endm - - .macro mask_pc, rd, rm - bic \rd, \rm, #PCMASK - .endm - - .macro enable_irqs, temp - teqp pc, #0x00000003 - .endm - - .macro initialise_traps_extra - .endm - - .macro get_thread_info, rd - mov \rd, sp, lsr #13 - mov \rd, \rd, lsl #13 - .endm - - /* - * Like adr, but force SVC mode (if required) - */ - .macro adrsvc, cond, reg, label - adr\cond \reg, \label - orr\cond \reg, \reg, #0x08000003 - .endm + .macro save_user_regs + str r0, [sp, #-4]! + str lr, [sp, #-4]! + sub sp, sp, #15*4 + stmia sp, {r0 - lr}^ + mov r0, r0 + .endm + + .macro restore_user_regs + ldmia sp, {r0 - lr}^ + mov r0, r0 + ldr lr, [sp, #15*4] + add sp, sp, #15*4+8 + movs pc, lr + .endm + + .macro fast_restore_user_regs + add sp, sp, #S_OFF + ldmib sp, {r1 - lr}^ + mov r0, r0 + ldr lr, [sp, #15*4] + add sp, sp, #15*4+8 + movs pc, lr + .endm + + .macro mask_pc, rd, rm + bic \rd, \rm, #PCMASK + .endm + + .macro enable_irqs, temp + teqp pc, #0x00000003 + .endm + + .macro initialise_traps_extra + .endm + + .macro get_thread_info, rd + mov \rd, sp, lsr #13 + mov \rd, \rd, lsl #13 + .endm + + /* + * Like adr, but force SVC mode (if required) + */ + .macro adrsvc, cond, reg, label + adr\cond \reg, \label + orr\cond \reg, \reg, #0x08000003 + .endm #endif @@ -215,13 +242,3 @@ tsk .req r9 @ current thread_info ldr scno, [lr, #-4] @ get SWI instruction #endif .endm - - .macro set_cpsr_c, reg, mode -#if 1 - mov \reg, \mode - msr cpsr_c, \reg -#else - msr cpsr_c, \mode -#endif - .endm - diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c index 79b647132c55..e8d788b364c7 100644 --- a/arch/arm/kernel/irq.c +++ b/arch/arm/kernel/irq.c @@ -217,14 +217,14 @@ do_simple_IRQ(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs) desc->triggered = 1; - irq_enter(cpu, irq); + irq_enter(); kstat.irqs[cpu][irq]++; action = desc->action; if (action) __do_irq(irq, desc->action, regs); - irq_exit(cpu, irq); + irq_exit(); } /* @@ -256,7 +256,7 @@ do_edge_IRQ(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs) */ desc->running = 1; - irq_enter(cpu, irq); + irq_enter(); kstat.irqs[cpu][irq]++; do { @@ -274,7 +274,7 @@ do_edge_IRQ(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs) __do_irq(irq, action, regs); } while (desc->pending); - irq_exit(cpu, irq); + irq_exit(); desc->running = 0; @@ -311,7 +311,7 @@ do_level_IRQ(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs) desc->chip->ack(irq); if (likely(desc->enabled)) { - irq_enter(cpu, irq); + irq_enter(); kstat.irqs[cpu][irq]++; /* @@ -325,7 +325,7 @@ do_level_IRQ(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs) !check_irq_lock(desc, irq, regs))) desc->chip->unmask(irq); } - irq_exit(cpu, irq); + irq_exit(); } } diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c index 1ec839acf394..9f325ea5dda6 100644 --- a/arch/arm/kernel/ptrace.c +++ b/arch/arm/kernel/ptrace.c @@ -17,6 +17,7 @@ #include <linux/smp_lock.h> #include <linux/ptrace.h> #include <linux/user.h> +#include <linux/security.h> #include <asm/uaccess.h> #include <asm/pgtable.h> @@ -655,6 +656,9 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) /* are we already being traced? */ if (current->ptrace & PT_PTRACED) goto out; + ret = security_ops->ptrace(current->parent, current); + if (ret) + goto out; /* set the ptrace bit in the process flags. */ current->ptrace |= PT_PTRACED; ret = 0; diff --git a/arch/arm/lib/kbd.c b/arch/arm/lib/kbd.c index 25ee8a5d33dd..23c74df7c4d0 100644 --- a/arch/arm/lib/kbd.c +++ b/arch/arm/lib/kbd.c @@ -1,13 +1,279 @@ #include <linux/config.h> #include <linux/kd.h> +#include <linux/kbd_ll.h> +#include <linux/kbd_kern.h> -int (*k_setkeycode)(unsigned int, unsigned int); -int (*k_getkeycode)(unsigned int); -int (*k_translate)(unsigned char, unsigned char *, char); -char (*k_unexpected_up)(unsigned char); +/* + * Translation of escaped scancodes to keycodes. + * This is now user-settable. + * The keycodes 1-88,96-111,119 are fairly standard, and + * should probably not be changed - changing might confuse X. + * X also interprets scancode 0x5d (KEY_Begin). + * + * For 1-88 keycode equals scancode. + */ + +#define E0_KPENTER 96 +#define E0_RCTRL 97 +#define E0_KPSLASH 98 +#define E0_PRSCR 99 +#define E0_RALT 100 +#define E0_BREAK 101 /* (control-pause) */ +#define E0_HOME 102 +#define E0_UP 103 +#define E0_PGUP 104 +#define E0_LEFT 105 +#define E0_RIGHT 106 +#define E0_END 107 +#define E0_DOWN 108 +#define E0_PGDN 109 +#define E0_INS 110 +#define E0_DEL 111 + +/* for USB 106 keyboard */ +#define E0_YEN 124 +#define E0_BACKSLASH 89 + + +#define E1_PAUSE 119 + +/* + * The keycodes below are randomly located in 89-95,112-118,120-127. + * They could be thrown away (and all occurrences below replaced by 0), + * but that would force many users to use the `setkeycodes' utility, where + * they needed not before. It does not matter that there are duplicates, as + * long as no duplication occurs for any single keyboard. + */ +#define SC_LIM 89 + +#define FOCUS_PF1 85 /* actual code! */ +#define FOCUS_PF2 89 +#define FOCUS_PF3 90 +#define FOCUS_PF4 91 +#define FOCUS_PF5 92 +#define FOCUS_PF6 93 +#define FOCUS_PF7 94 +#define FOCUS_PF8 95 +#define FOCUS_PF9 120 +#define FOCUS_PF10 121 +#define FOCUS_PF11 122 +#define FOCUS_PF12 123 + +#define JAP_86 124 +/* tfj@olivia.ping.dk: + * The four keys are located over the numeric keypad, and are + * labelled A1-A4. It's an rc930 keyboard, from + * Regnecentralen/RC International, Now ICL. + * Scancodes: 59, 5a, 5b, 5c. + */ +#define RGN1 124 +#define RGN2 125 +#define RGN3 126 +#define RGN4 127 + +static unsigned char high_keys[128 - SC_LIM] = { + RGN1, RGN2, RGN3, RGN4, 0, 0, 0, /* 0x59-0x5f */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60-0x67 */ + 0, 0, 0, 0, 0, FOCUS_PF11, 0, FOCUS_PF12, /* 0x68-0x6f */ + 0, 0, 0, FOCUS_PF2, FOCUS_PF9, 0, 0, FOCUS_PF3, /* 0x70-0x77 */ + FOCUS_PF4, FOCUS_PF5, FOCUS_PF6, FOCUS_PF7, /* 0x78-0x7b */ + FOCUS_PF8, JAP_86, FOCUS_PF10, 0 /* 0x7c-0x7f */ +}; + +/* BTC */ +#define E0_MACRO 112 +/* LK450 */ +#define E0_F13 113 +#define E0_F14 114 +#define E0_HELP 115 +#define E0_DO 116 +#define E0_F17 117 +#define E0_KPMINPLUS 118 +/* + * My OmniKey generates e0 4c for the "OMNI" key and the + * right alt key does nada. [kkoller@nyx10.cs.du.edu] + */ +#define E0_OK 124 +/* + * New microsoft keyboard is rumoured to have + * e0 5b (left window button), e0 5c (right window button), + * e0 5d (menu button). [or: LBANNER, RBANNER, RMENU] + * [or: Windows_L, Windows_R, TaskMan] + */ +#define E0_MSLW 125 +#define E0_MSRW 126 +#define E0_MSTM 127 + +static unsigned char e0_keys[128] = { + 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00-0x07 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 0x08-0x0f */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10-0x17 */ + 0, 0, 0, 0, E0_KPENTER, E0_RCTRL, 0, 0, /* 0x18-0x1f */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20-0x27 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 0x28-0x2f */ + 0, 0, 0, 0, 0, E0_KPSLASH, 0, E0_PRSCR, /* 0x30-0x37 */ + E0_RALT, 0, 0, 0, 0, E0_F13, E0_F14, E0_HELP, /* 0x38-0x3f */ + E0_DO, E0_F17, 0, 0, 0, 0, E0_BREAK, E0_HOME, /* 0x40-0x47 */ + E0_UP, E0_PGUP, 0, E0_LEFT, E0_OK, E0_RIGHT, E0_KPMINPLUS, E0_END, /* 0x48-0x4f */ + E0_DOWN, E0_PGDN, E0_INS, E0_DEL, 0, 0, 0, 0, /* 0x50-0x57 */ + 0, 0, 0, E0_MSLW, E0_MSRW, E0_MSTM, 0, 0, /* 0x58-0x5f */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60-0x67 */ + 0, 0, 0, 0, 0, 0, 0, E0_MACRO, /* 0x68-0x6f */ + //0, 0, 0, 0, 0, 0, 0, 0, /* 0x70-0x77 */ + 0, 0, 0, 0, 0, E0_BACKSLASH, 0, 0, /* 0x70-0x77 */ + 0, 0, 0, E0_YEN, 0, 0, 0, 0 /* 0x78-0x7f */ +}; + +static int gen_setkeycode(unsigned int scancode, unsigned int keycode) +{ + if (scancode < SC_LIM || scancode > 255 || keycode > 127) + return -EINVAL; + if (scancode < 128) + high_keys[scancode - SC_LIM] = keycode; + else + e0_keys[scancode - 128] = keycode; + return 0; +} + +static int gen_getkeycode(unsigned int scancode) +{ + return + (scancode < SC_LIM || scancode > 255) ? -EINVAL : + (scancode < + 128) ? high_keys[scancode - SC_LIM] : e0_keys[scancode - 128]; +} + +static int +gen_translate(unsigned char scancode, unsigned char *keycode, char raw_mode) +{ + static int prev_scancode = 0; + + /* special prefix scancodes.. */ + if (scancode == 0xe0 || scancode == 0xe1) { + prev_scancode = scancode; + return 0; + } + + /* 0xFF is sent by a few keyboards, ignore it. 0x00 is error */ + if (scancode == 0x00 || scancode == 0xff) { + prev_scancode = 0; + return 0; + } + + scancode &= 0x7f; + + if (prev_scancode) { + /* + * usually it will be 0xe0, but a Pause key generates + * e1 1d 45 e1 9d c5 when pressed, and nothing when released + */ + if (prev_scancode != 0xe0) { + if (prev_scancode == 0xe1 && scancode == 0x1d) { + prev_scancode = 0x100; + return 0; + } + else if (prev_scancode == 0x100 + && scancode == 0x45) { + *keycode = E1_PAUSE; + prev_scancode = 0; + } else { +#ifdef KBD_REPORT_UNKN + if (!raw_mode) + printk(KERN_INFO + "keyboard: unknown e1 escape sequence\n"); +#endif + prev_scancode = 0; + return 0; + } + } else { + prev_scancode = 0; + /* + * The keyboard maintains its own internal caps lock and + * num lock statuses. In caps lock mode E0 AA precedes make + * code and E0 2A follows break code. In num lock mode, + * E0 2A precedes make code and E0 AA follows break code. + * We do our own book-keeping, so we will just ignore these. + */ + /* + * For my keyboard there is no caps lock mode, but there are + * both Shift-L and Shift-R modes. The former mode generates + * E0 2A / E0 AA pairs, the latter E0 B6 / E0 36 pairs. + * So, we should also ignore the latter. - aeb@cwi.nl + */ + if (scancode == 0x2a || scancode == 0x36) + return 0; + + if (e0_keys[scancode]) + *keycode = e0_keys[scancode]; + else { +#ifdef KBD_REPORT_UNKN + if (!raw_mode) + printk(KERN_INFO + "keyboard: unknown scancode e0 %02x\n", + scancode); +#endif + return 0; + } + } + } else if (scancode >= SC_LIM) { + /* This happens with the FOCUS 9000 keyboard + Its keys PF1..PF12 are reported to generate + 55 73 77 78 79 7a 7b 7c 74 7e 6d 6f + Moreover, unless repeated, they do not generate + key-down events, so we have to zero up_flag below */ + /* Also, Japanese 86/106 keyboards are reported to + generate 0x73 and 0x7d for \ - and \ | respectively. */ + /* Also, some Brazilian keyboard is reported to produce + 0x73 and 0x7e for \ ? and KP-dot, respectively. */ + + *keycode = high_keys[scancode - SC_LIM]; + + if (!*keycode) { + if (!raw_mode) { +#ifdef KBD_REPORT_UNKN + printk(KERN_INFO + "keyboard: unrecognized scancode (%02x)" + " - ignored\n", scancode); +#endif + } + return 0; + } + } else + *keycode = scancode; + return 1; +} + +static char gen_unexpected_up(unsigned char keycode) +{ + /* unexpected, but this can happen: maybe this was a key release for a + FOCUS 9000 PF key; if we want to see it, we have to clear up_flag */ + if (keycode >= SC_LIM || keycode == 85) + return 0; + else + return 0200; +} + +/* + * These are the default mappings + */ +int (*k_setkeycode)(unsigned int, unsigned int) = gen_setkeycode; +int (*k_getkeycode)(unsigned int) = gen_getkeycode; +int (*k_translate)(unsigned char, unsigned char *, char) = gen_translate; +char (*k_unexpected_up)(unsigned char) = gen_unexpected_up; void (*k_leds)(unsigned char); +/* Simple translation table for the SysRq keys */ + #ifdef CONFIG_MAGIC_SYSRQ -int k_sysrq_key; -unsigned char *k_sysrq_xlate; +static unsigned char gen_sysrq_xlate[128] = + "\000\0331234567890-=\177\t" /* 0x00 - 0x0f */ + "qwertyuiop[]\r\000as" /* 0x10 - 0x1f */ + "dfghjkl;'`\000\\zxcv" /* 0x20 - 0x2f */ + "bnm,./\000*\000 \000\201\202\203\204\205" /* 0x30 - 0x3f */ + "\206\207\210\211\212\000\000789-456+1" /* 0x40 - 0x4f */ + "230\177\000\000\213\214\000\000\000\000\000\000\000\000\000\000" /* 0x50 - 0x5f */ + "\r\000/"; /* 0x60 - 0x6f */ + +unsigned char *k_sysrq_xlate = gen_sysrq_xlate; +int k_sysrq_key = 0x54; #endif diff --git a/arch/arm/mach-integrator/cpu.c b/arch/arm/mach-integrator/cpu.c index f2e7938bcc42..7ef1c9cee426 100644 --- a/arch/arm/mach-integrator/cpu.c +++ b/arch/arm/mach-integrator/cpu.c @@ -1,9 +1,9 @@ /* * linux/arch/arm/mach-integrator/cpu.c * - * Copyright (C) 2001 Deep Blue Solutions Ltd. + * Copyright (C) 2001-2002 Deep Blue Solutions Ltd. * - * $Id: cpu.c,v 1.5 2002/07/06 16:53:17 rmk Exp $ + * $Id: cpu.c,v 1.6 2002/07/18 13:58:51 rmk Exp $ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -15,6 +15,9 @@ #include <linux/types.h> #include <linux/kernel.h> #include <linux/cpufreq.h> +#include <linux/slab.h> +#include <linux/sched.h> +#include <linux/smp.h> #include <linux/init.h> #include <asm/hardware.h> @@ -42,7 +45,7 @@ static unsigned int vco_to_freq(struct vco vco, int factor) #ifdef CONFIG_CPU_FREQ /* - * Divisor indexes for in ascending divisor order + * Divisor indexes in ascending divisor order */ static unsigned char s2od[] = { 1, 3, 4, 7, 5, 2, 6, 0 }; @@ -70,7 +73,8 @@ static struct vco freq_to_vco(unsigned int freq_khz, int factor) * Validate the speed in khz. If it is outside our * range, then return the lowest. */ -unsigned int integrator_validatespeed(unsigned int freq_khz) +static unsigned int +integrator_validatespeed(unsigned int cpu, unsigned int freq_khz) { struct vco vco; @@ -87,11 +91,21 @@ unsigned int integrator_validatespeed(unsigned int freq_khz) return vco_to_freq(vco, 1); } -void integrator_setspeed(unsigned int freq_khz) +static void integrator_setspeed(unsigned int cpu, unsigned int freq_khz) { struct vco vco = freq_to_vco(freq_khz, 1); + unsigned long cpus_allowed; u_int cm_osc; + /* + * Save this threads cpus_allowed mask, and bind to the + * specified CPU. When this call returns, we should be + * running on the right CPU. + */ + cpus_allowed = current->cpus_allowed; + set_cpus_allowed(current, 1 << cpu); + BUG_ON(cpu != smp_processor_id()); + cm_osc = __raw_readl(CM_OSC); cm_osc &= 0xfffff800; cm_osc |= vco.vdw | vco.od << 8; @@ -99,44 +113,72 @@ void integrator_setspeed(unsigned int freq_khz) __raw_writel(0xa05f, CM_LOCK); __raw_writel(cm_osc, CM_OSC); __raw_writel(0, CM_LOCK); + + /* + * Restore the CPUs allowed mask. + */ + set_cpus_allowed(current, cpus_allowed); } + +static struct cpufreq_driver integrator_driver = { + .validate = integrator_validatespeed, + .setspeed = integrator_setspeed, + .sync = 1, +}; #endif -static int __init cpu_init(void) +static int __init integrator_cpu_init(void) { - u_int cm_osc, cm_stat, cpu_freq_khz, mem_freq_khz; - struct vco vco; + struct cpufreq_freqs *freqs; + unsigned long cpus_allowed; + int cpu; + + freqs = kmalloc(sizeof(struct cpufreq_freqs) * NR_CPUS, + GFP_KERNEL); + if (!freqs) { + printk(KERN_ERR "CPU: unable to allocate cpufreqs structure\n"); + return -ENOMEM; + } - cm_osc = __raw_readl(CM_OSC); + cpus_allowed = current->cpus_allowed; + for (cpu = 0; cpu < NR_CPUS; cpu++) { + u_int cm_osc, cm_stat, mem_freq_khz; + struct vco vco; - vco.od = (cm_osc >> 20) & 7; - vco.vdw = (cm_osc >> 12) & 255; - mem_freq_khz = vco_to_freq(vco, 2); + if (!cpu_online(cpu)) + continue; - printk(KERN_INFO "Memory clock = %d.%03d MHz\n", - mem_freq_khz / 1000, mem_freq_khz % 1000); + set_cpus_allowed(current, 1 << cpu); + BUG_ON(cpu != smp_processor_id()); - vco.od = (cm_osc >> 8) & 7; - vco.vdw = cm_osc & 255; - cpu_freq_khz = vco_to_freq(vco, 1); + cm_stat = __raw_readl(CM_STAT); + cm_osc = __raw_readl(CM_OSC); + vco.od = (cm_osc >> 20) & 7; + vco.vdw = (cm_osc >> 12) & 255; + mem_freq_khz = vco_to_freq(vco, 2); -#ifdef CONFIG_CPU_FREQ - { - struct cpufreq_driver cpufreq_driver; - - cpufreq_driver.freq.min = 12000; - cpufreq_driver.freq.max = 160000; - cpufreq_driver.freq.cur = cpu_freq_khz; - cpufreq_driver.validate = &integrator_validatespeed; - cpufreq_driver.setspeed = &integrator_setspeed; - cpufreq_register(cpufreq_driver); + printk(KERN_INFO "CPU%d: Module id: %d\n", cpu, cm_stat & 255); + printk(KERN_INFO "CPU%d: Memory clock = %d.%03d MHz\n", + cpu, mem_freq_khz / 1000, mem_freq_khz % 1000); + + vco.od = (cm_osc >> 8) & 7; + vco.vdw = cm_osc & 255; + + freqs[cpu].min = 12000; + freqs[cpu].max = 160000; + freqs[cpu].cur = vco_to_freq(vco, 1); } -#endif - cm_stat = __raw_readl(CM_STAT); - printk("Module id: %d\n", cm_stat & 255); + set_cpus_allowed(current, cpus_allowed); + +#ifdef CONFIG_CPU_FREQ + integrator_driver.freq = freqs; + cpufreq_register(&integrator_driver); +#else + kfree(freqs); +#endif return 0; } -__initcall(cpu_init); +__initcall(integrator_cpu_init); diff --git a/arch/arm/mach-sa1100/adsbitsy.c b/arch/arm/mach-sa1100/adsbitsy.c index dae8502155b6..30e401122666 100644 --- a/arch/arm/mach-sa1100/adsbitsy.c +++ b/arch/arm/mach-sa1100/adsbitsy.c @@ -18,6 +18,7 @@ #include <linux/serial_core.h> #include <asm/hardware.h> +#include <asm/mach-types.h> #include <asm/setup.h> #include <asm/irq.h> diff --git a/arch/arm/mach-sa1100/assabet.c b/arch/arm/mach-sa1100/assabet.c index f6ab3d2415c0..124a2ea93a48 100644 --- a/arch/arm/mach-sa1100/assabet.c +++ b/arch/arm/mach-sa1100/assabet.c @@ -20,6 +20,7 @@ #include <linux/serial_core.h> #include <asm/hardware.h> +#include <asm/mach-types.h> #include <asm/irq.h> #include <asm/setup.h> #include <asm/page.h> diff --git a/arch/arm/mach-sa1100/badge4.c b/arch/arm/mach-sa1100/badge4.c index 4625493b729c..029680a5ba03 100644 --- a/arch/arm/mach-sa1100/badge4.c +++ b/arch/arm/mach-sa1100/badge4.c @@ -22,6 +22,7 @@ #include <linux/errno.h> #include <asm/hardware.h> +#include <asm/mach-types.h> #include <asm/setup.h> #include <asm/arch/irqs.h> diff --git a/arch/arm/mach-sa1100/cpu-sa1100.c b/arch/arm/mach-sa1100/cpu-sa1100.c index dd353855e3f8..1d2805f85696 100644 --- a/arch/arm/mach-sa1100/cpu-sa1100.c +++ b/arch/arm/mach-sa1100/cpu-sa1100.c @@ -91,7 +91,7 @@ #include <asm/hardware.h> extern unsigned int sa11x0_freq_to_ppcr(unsigned int khz); -extern unsigned int sa11x0_validatespeed(unsigned int khz); +extern unsigned int sa11x0_validatespeed(unsigned int cpu, unsigned int khz); extern unsigned int sa11x0_getspeed(void); typedef struct { @@ -220,29 +220,35 @@ static struct notifier_block sa1100_dram_block = { }; -static void sa1100_setspeed(unsigned int khz) +static void sa1100_setspeed(unsigned int cpu, unsigned int khz) { PPCR = sa11x0_freq_to_ppcr(khz); } +static struct cpufreq_freqs sa1100_freqs = { + .min = 59000, + .max = 287000, +}; + +static struct cpufreq_driver sa1100_driver = { + .freq = &sa1100_freqs, + .validate = sa11x0_validatespeed, + .setspeed = sa1100_setspeed, + .sync = 1, +}; + static int __init sa1100_dram_init(void) { int ret = -ENODEV; if ((processor_id & CPU_SA1100_MASK) == CPU_SA1100_ID) { - cpufreq_driver_t cpufreq_driver; - ret = cpufreq_register_notifier(&sa1100_dram_block); if (ret) return ret; - cpufreq_driver.freq.min = 59000; - cpufreq_driver.freq.max = 287000; - cpufreq_driver.freq.cur = sa11x0_getspeed(); - cpufreq_driver.validate = &sa11x0_validatespeed; - cpufreq_driver.setspeed = &sa1100_setspeed; + sa1100_freqs.cur = sa11x0_getspeed(); - ret = cpufreq_register(cpufreq_driver);< + ret = cpufreq_register(&sa1100_driver); } return ret; diff --git a/arch/arm/mach-sa1100/cpu-sa1110.c b/arch/arm/mach-sa1100/cpu-sa1110.c index bdd74df51ad4..e4e2c1b22adc 100644 --- a/arch/arm/mach-sa1100/cpu-sa1110.c +++ b/arch/arm/mach-sa1100/cpu-sa1110.c @@ -24,13 +24,14 @@ #include <linux/init.h> #include <asm/hardware.h> +#include <asm/mach-types.h> #include <asm/io.h> #include <asm/system.h> #undef DEBUG extern unsigned int sa11x0_freq_to_ppcr(unsigned int khz); -extern unsigned int sa11x0_validatespeed(unsigned int khz); +extern unsigned int sa11x0_validatespeed(unsigned int cpu, unsigned int khz); extern unsigned int sa11x0_getspeed(void); struct sdram_params { @@ -213,7 +214,7 @@ sdram_update_refresh(u_int cpu_khz, struct sdram_params *sdram) * above, we can match for an exact frequency. If we don't find * an exact match, we will to set the lowest frequency to be safe. */ -static void sa1110_setspeed(unsigned int khz) +static void sa1110_setspeed(unsigned int cpu, unsigned int khz) { struct sdram_params *sdram = &sdram_params; struct sdram_info sd; @@ -284,6 +285,18 @@ static void sa1110_setspeed(unsigned int khz) sdram_update_refresh(khz, sdram); } +static struct cpufreq_freqs sa1110_freqs = { + .min = 59000, + .max = 287000, +}; + +static struct cpufreq_driver sa1110_driver = { + .freq = &sa1110_freqs, + .validate = sa11x0_validatespeed, + .setspeed = sa1110_setspeed, + .sync = 1, +}; + static int __init sa1110_clk_init(void) { struct sdram_params *sdram = NULL; @@ -298,8 +311,6 @@ static int __init sa1110_clk_init(void) sdram = &samsung_km416s4030ct; if (sdram) { - struct cpufreq_driver cpufreq_driver; - printk(KERN_DEBUG "SDRAM: tck: %d trcd: %d trp: %d" " twr: %d refresh: %d cas_latency: %d\n", sdram->tck, sdram->trcd, sdram->trp, @@ -307,15 +318,10 @@ static int __init sa1110_clk_init(void) memcpy(&sdram_params, sdram, sizeof(sdram_params)); - sa1110_setspeed(sa11x0_getspeed()); - - cpufreq_driver.freq.min = 59000; - cpufreq_driver.freq.max = 287000; - cpufreq_driver.freq.cur = sa11x0_getspeed(); - cpufreq_driver.validate = &sa11x0_validatespeed; - cpufreq_driver.setspeed = &sa1110_setspeed; + sa1110_freqs.cur = sa11x0_getspeed(); + sa1110_setspeed(0, sa1110_freqs.cur); - return cpufreq_register(cpufreq_driver); + return cpufreq_register(&sa1110_driver); } return 0; diff --git a/arch/arm/mach-sa1100/freebird.c b/arch/arm/mach-sa1100/freebird.c index 9217aa3aed6f..bb50c58a1f38 100644 --- a/arch/arm/mach-sa1100/freebird.c +++ b/arch/arm/mach-sa1100/freebird.c @@ -9,6 +9,7 @@ #include <linux/tty.h> #include <asm/hardware.h> +#include <asm/mach-types.h> #include <asm/setup.h> #include <asm/mach/arch.h> diff --git a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c index 43425899690b..bb481b9f5d34 100644 --- a/arch/arm/mach-sa1100/generic.c +++ b/arch/arm/mach-sa1100/generic.c @@ -71,7 +71,7 @@ unsigned int sa11x0_freq_to_ppcr(unsigned int khz) * Validate the speed in khz. If we can't generate the precise * frequency requested, round it down (to be on the safe side). */ -unsigned int sa11x0_validatespeed(unsigned int khz) +unsigned int sa11x0_validatespeed(unsigned int cpu, unsigned int khz) { return cclk_frequency_100khz[sa11x0_freq_to_ppcr(khz)] * 100; } diff --git a/arch/arm/mach-sa1100/graphicsmaster.c b/arch/arm/mach-sa1100/graphicsmaster.c index 1c31e2bd791c..ed144191fa1c 100644 --- a/arch/arm/mach-sa1100/graphicsmaster.c +++ b/arch/arm/mach-sa1100/graphicsmaster.c @@ -15,6 +15,7 @@ #include <linux/ioport.h> #include <asm/hardware.h> +#include <asm/mach-types.h> #include <asm/setup.h> #include <asm/irq.h> diff --git a/arch/arm/mach-sa1100/h3600.c b/arch/arm/mach-sa1100/h3600.c index befe3fa5a93e..000125e4f95a 100644 --- a/arch/arm/mach-sa1100/h3600.c +++ b/arch/arm/mach-sa1100/h3600.c @@ -27,6 +27,7 @@ #include <asm/irq.h> #include <asm/hardware.h> +#include <asm/mach-types.h> #include <asm/setup.h> #include <asm/mach/arch.h> diff --git a/arch/arm/mach-sa1100/huw_webpanel.c b/arch/arm/mach-sa1100/huw_webpanel.c index 2015e3f5c094..348bbaa9c078 100644 --- a/arch/arm/mach-sa1100/huw_webpanel.c +++ b/arch/arm/mach-sa1100/huw_webpanel.c @@ -8,6 +8,7 @@ #include <linux/tty.h> #include <asm/hardware.h> +#include <asm/mach-types.h> #include <asm/setup.h> #include <asm/mach/arch.h> diff --git a/arch/arm/mach-sa1100/neponset.c b/arch/arm/mach-sa1100/neponset.c index bdcef2cb001a..a731a2680d84 100644 --- a/arch/arm/mach-sa1100/neponset.c +++ b/arch/arm/mach-sa1100/neponset.c @@ -13,6 +13,7 @@ #include <linux/device.h> #include <asm/hardware.h> +#include <asm/mach-types.h> #include <asm/irq.h> #include <asm/mach/map.h> #include <asm/mach/irq.h> diff --git a/arch/arm/mach-sa1100/omnimeter.c b/arch/arm/mach-sa1100/omnimeter.c index 8666559dcf7c..0da9d76637b8 100644 --- a/arch/arm/mach-sa1100/omnimeter.c +++ b/arch/arm/mach-sa1100/omnimeter.c @@ -7,6 +7,7 @@ #include <linux/tty.h> #include <asm/hardware.h> +#include <asm/mach-types.h> #include <asm/setup.h> #include <asm/mach/arch.h> diff --git a/arch/arm/mach-sa1100/pfs168.c b/arch/arm/mach-sa1100/pfs168.c index 34ef3dc3ad4d..b374138964b3 100644 --- a/arch/arm/mach-sa1100/pfs168.c +++ b/arch/arm/mach-sa1100/pfs168.c @@ -9,6 +9,7 @@ #include <linux/ioport.h> #include <asm/hardware.h> +#include <asm/mach-types.h> #include <asm/setup.h> #include <asm/mach/arch.h> diff --git a/arch/arm/mach-sa1100/sa1111.c b/arch/arm/mach-sa1100/sa1111.c index b54e48622b68..90f62e5fffee 100644 --- a/arch/arm/mach-sa1100/sa1111.c +++ b/arch/arm/mach-sa1100/sa1111.c @@ -27,6 +27,7 @@ #include <linux/slab.h> #include <asm/hardware.h> +#include <asm/mach-types.h> #include <asm/io.h> #include <asm/irq.h> #include <asm/mach/irq.h> diff --git a/arch/arm/mach-sa1100/system3.c b/arch/arm/mach-sa1100/system3.c index 397b35c84d3c..67588f3e407d 100644 --- a/arch/arm/mach-sa1100/system3.c +++ b/arch/arm/mach-sa1100/system3.c @@ -44,9 +44,8 @@ #include <linux/cpufreq.h> #include <asm/hardware.h> +#include <asm/mach-types.h> #include <asm/setup.h> -#include <asm/page.h> -#include <asm/pgtable.h> #include <asm/irq.h> #include <asm/mach/arch.h> diff --git a/arch/arm/mach-sa1100/yopy.c b/arch/arm/mach-sa1100/yopy.c index f52c5d7683ee..dc6ea9d9dfeb 100644 --- a/arch/arm/mach-sa1100/yopy.c +++ b/arch/arm/mach-sa1100/yopy.c @@ -7,6 +7,7 @@ #include <linux/tty.h> #include <asm/hardware.h> +#include <asm/mach-types.h> #include <asm/setup.h> #include <asm/mach/arch.h> diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c index 0b678b1d7fdd..76120ee59dea 100644 --- a/arch/arm/mm/alignment.c +++ b/arch/arm/mm/alignment.c @@ -399,13 +399,13 @@ do_alignment_ldmstm(unsigned long addr, unsigned long instr, struct pt_regs *reg eaddr += 4; /* - * For alignment faults on the ARM922T the MMU makes + * For alignment faults on the ARM922T/ARM920T the MMU makes * the FSR (and hence addr) equal to the updated base address * of the multiple access rather than the restored value. - * Switch this messsage off if we've got a ARM922, otherwise + * Switch this messsage off if we've got a ARM92[02], otherwise * [ls]dm alignment faults are noisy! */ -#if !(defined CONFIG_CPU_ARM922T) +#if !(defined CONFIG_CPU_ARM922T) && !(defined CONFIG_CPU_ARM920T) /* * This is a "hint" - we already have eaddr worked out by the * processor for us. diff --git a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c index c78f30319470..259f7541a875 100644 --- a/arch/arm/mm/mm-armv.c +++ b/arch/arm/mm/mm-armv.c @@ -17,6 +17,7 @@ #include <asm/pgtable.h> #include <asm/pgalloc.h> #include <asm/page.h> +#include <asm/rmap.h> #include <asm/io.h> #include <asm/setup.h> @@ -149,6 +150,7 @@ void free_pgd_slow(pgd_t *pgd) pte = pmd_page(*pmd); pmd_clear(pmd); + pgtable_remove_rmap(pte); pte_free(pte); pmd_free(pmd); free: diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types index 11418b2291b3..39e28f196918 100644 --- a/arch/arm/tools/mach-types +++ b/arch/arm/tools/mach-types @@ -6,7 +6,7 @@ # To add an entry into this database, please see Documentation/arm/README, # or contact rmk@arm.linux.org.uk # -# Last update: Fri Jul 5 21:32:20 2002 +# Last update: Sat Jul 27 09:56:53 2002 # # machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number # @@ -175,7 +175,7 @@ amico ARCH_AMICO AMICO 163 iam SA1100_IAM IAM 164 tt530 SA1100_TT530 TT530 165 sam2400 ARCH_SAM2400 SAM2400 166 -jornada56x ARCH_JORNADA56X JORNADA56X 167 +jornada56x SA1100_JORNADA56X JORNADA56X 167 active SA1100_ACTIVE ACTIVE 168 iq80321 ARCH_IQ80321 IQ80321 169 wid SA1100_WID WID 170 @@ -207,3 +207,10 @@ nexio SA1100_NEXIO NEXIO 195 bitbox SA1100_BITBOX BITBOX 196 g200 SA1100_G200 G200 197 gill SA1100_GILL GILL 198 +pxa_mercury ARCH_PXA_MERCURY PXA_MERCURY 199 +ceiva ARCH_CEIVA CEIVA 200 +fret SA1100_FRET FRET 201 +emailphone SA1100_EMAILPHONE EMAILPHONE 202 +h3900 ARCH_H3900 H3900 203 +pxa1 ARCH_PXA1 PXA1 204 +koan369 SA1100_KOAN369 KOAN369 205 diff --git a/arch/i386/kernel/i8259.c b/arch/i386/kernel/i8259.c index 47489200339b..6e875d22283f 100644 --- a/arch/i386/kernel/i8259.c +++ b/arch/i386/kernel/i8259.c @@ -38,7 +38,8 @@ spinlock_t i8259A_lock = SPIN_LOCK_UNLOCKED; static void end_8259A_irq (unsigned int irq) { - if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)) && + irq_desc[irq].action) enable_8259A_irq(irq); } diff --git a/arch/i386/kernel/irq.c b/arch/i386/kernel/irq.c index 85c360b3db51..039ba8a226a4 100644 --- a/arch/i386/kernel/irq.c +++ b/arch/i386/kernel/irq.c @@ -187,10 +187,6 @@ int show_interrupts(struct seq_file *p, void *v) #if CONFIG_SMP inline void synchronize_irq(unsigned int irq) { - /* is there anything to synchronize with? */ - if (!irq_desc[irq].action) - return; - while (irq_desc[irq].status & IRQ_INPROGRESS) cpu_relax(); } @@ -350,7 +346,7 @@ asmlinkage unsigned int do_IRQ(struct pt_regs regs) * use the action we have. */ action = NULL; - if (!(status & (IRQ_DISABLED | IRQ_INPROGRESS))) { + if (likely(!(status & (IRQ_DISABLED | IRQ_INPROGRESS)))) { action = desc->action; status &= ~IRQ_PENDING; /* we commit to handling */ status |= IRQ_INPROGRESS; /* we are handling it */ @@ -363,7 +359,7 @@ asmlinkage unsigned int do_IRQ(struct pt_regs regs) a different instance of this same irq, the other processor will take care of it. */ - if (!action) + if (unlikely(!action)) goto out; /* @@ -381,12 +377,12 @@ asmlinkage unsigned int do_IRQ(struct pt_regs regs) handle_IRQ_event(irq, ®s, action); spin_lock(&desc->lock); - if (!(desc->status & IRQ_PENDING)) + if (likely(!(desc->status & IRQ_PENDING))) break; desc->status &= ~IRQ_PENDING; } - desc->status &= ~IRQ_INPROGRESS; out: + desc->status &= ~IRQ_INPROGRESS; /* * The ->end() handler has to deal with interrupts which got * disabled while the handler was running. diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c index 23b997cd5d5e..36ae42521b04 100644 --- a/arch/i386/mm/init.c +++ b/arch/i386/mm/init.c @@ -54,7 +54,7 @@ static pmd_t * __init one_md_table_init(pgd_t *pgd) #if CONFIG_X86_PAE pmd_table = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE); - set_pgd(pgd, __pgd(__pa(md_table) | _PAGE_PRESENT)); + set_pgd(pgd, __pgd(__pa(pmd_table) | _PAGE_PRESENT)); if (pmd_table != pmd_offset(pgd, 0)) BUG(); #else diff --git a/drivers/ide/cmd640.c b/drivers/ide/cmd640.c index e8325b9e7690..9ed46b2688f9 100644 --- a/drivers/ide/cmd640.c +++ b/drivers/ide/cmd640.c @@ -109,6 +109,7 @@ #include <linux/init.h> #include <linux/hdreg.h> #include <linux/ide.h> +#include <linux/pci.h> #include <asm/io.h> @@ -164,6 +165,12 @@ int cmd640_vlb = 0; #define BRST 0x59 /* + * Protects register file access from overlapping on primary and secondary + * channel, since those share hardware resources. + */ +static spinlock_t cmd640_lock __cacheline_aligned = SPIN_LOCK_UNLOCKED; + +/* * Registers and masks for easy access by drive index: */ static u8 prefetch_regs[4] = {CNTRL, CNTRL, ARTTIM23, ARTTIM23}; @@ -171,12 +178,6 @@ static u8 prefetch_masks[4] = {CNTRL_DIS_RA0, CNTRL_DIS_RA1, ARTTIM23_DIS_RA2, A #ifdef CONFIG_BLK_DEV_CMD640_ENHANCED -/* - * Protects register file access from overlapping on primary and secondary - * channel, since those share hardware resources. - */ -static spinlock_t cmd640_lock __cacheline_aligned = SPIN_LOCK_UNLOCKED; - static u8 arttim_regs[4] = {ARTTIM0, ARTTIM1, ARTTIM23, ARTTIM23}; static u8 drwtim_regs[4] = {DRWTIM0, DRWTIM1, DRWTIM23, DRWTIM23}; @@ -214,19 +215,16 @@ static unsigned int cmd640_chip_version; * Therefore, we must use direct IO instead. */ -/* This is broken, but no more so than the old code.. */ -static spinlock_t cmd640_lock = SPIN_LOCK_UNLOCKED; - /* PCI method 1 access */ static void put_cmd640_reg_pci1 (unsigned short reg, u8 val) { unsigned long flags; - - spin_lock_irqsave(&cmd640_lock, flags); - outl_p((reg & 0xfc) | cmd640_key, 0xcf8); + + spin_lock_irqsave(&pci_lock, flags); + outb_p((reg & 0xfc) | cmd640_key, 0xcf8); outb_p(val, (reg & 3) | 0xcfc); - spin_unlock_irqrestore(&cmd640_lock, flags); + spin_unlock_irqrestore(&pci_lock, flags); } static u8 get_cmd640_reg_pci1 (unsigned short reg) @@ -234,10 +232,10 @@ static u8 get_cmd640_reg_pci1 (unsigned short reg) u8 b; unsigned long flags; - spin_lock_irqsave(&cmd640_lock, flags); - outl_p((reg & 0xfc) | cmd640_key, 0xcf8); - b = inb_p((reg & 3) | 0xcfc); - spin_unlock_irqrestore(&cmd640_lock, flags); + spin_lock_irqsave(&pci_lock, flags); + outb_p((reg & 0xfc) | cmd640_key, 0xcf8); + b=inb_p((reg & 3) | 0xcfc); + spin_unlock_irqrestore(&pci_lock, flags); return b; } @@ -247,11 +245,11 @@ static void put_cmd640_reg_pci2 (unsigned short reg, u8 val) { unsigned long flags; - spin_lock_irqsave(&cmd640_lock, flags); + spin_lock_irqsave(&pci_lock, flags); outb_p(0x10, 0xcf8); outb_p(val, cmd640_key + reg); outb_p(0, 0xcf8); - spin_unlock_irqrestore(&cmd640_lock, flags); + spin_unlock_irqrestore(&pci_lock, flags); } static u8 get_cmd640_reg_pci2 (unsigned short reg) @@ -259,11 +257,11 @@ static u8 get_cmd640_reg_pci2 (unsigned short reg) u8 b; unsigned long flags; - spin_lock_irqsave(&cmd640_lock, flags); + spin_lock_irqsave(&pci_lock, flags); outb_p(0x10, 0xcf8); b = inb_p(cmd640_key + reg); outb_p(0, 0xcf8); - spin_unlock_irqrestore(&cmd640_lock, flags); + spin_unlock_irqrestore(&pci_lock, flags); return b; } @@ -574,7 +572,7 @@ static void program_drive_counts (unsigned int index) /* * Now that everything is ready, program the new timings */ - spin_lock(&cmd640_lock, flags); + spin_lock_irqsave(&cmd640_lock, flags); /* * Program the address_setup clocks into ARTTIM reg, * and then the active/recovery counts into the DRWTIM reg @@ -695,9 +693,61 @@ out_lock: #endif +/** + * pci_conf1 - check for PCI type 1 configuration + * + * Issues a safe probe sequence for PCI configuration type 1 and + * returns non-zero if conf1 is supported. Takes the pci_config lock + */ + +static int pci_conf1(void) +{ + u32 tmp; + unsigned long flags; + + spin_lock_irqsave(&pci_lock, flags); + + OUT_BYTE(0x01, 0xCFB); + tmp = inl(0xCF8); + outl(0x80000000, 0xCF8); + if (inl(0xCF8) == 0x80000000) { + spin_unlock_irqrestore(&pci_lock, flags); + outl(tmp, 0xCF8); + return 1; + } + outl(tmp, 0xCF8); + spin_unlock_irqrestore(&pci_lock, flags); + return 0; +} + +/** + * pci_conf2 - check for PCI type 2 configuration + * + * Issues a safe probe sequence for PCI configuration type 2 and + * returns non-zero if conf2 is supported. Takes the pci_config lock. + */ + + +static int pci_conf2(void) +{ + unsigned long flags; + spin_lock_irqsave(&pci_lock, flags); + + OUT_BYTE(0x00, 0xCFB); + OUT_BYTE(0x00, 0xCF8); + OUT_BYTE(0x00, 0xCFA); + if (IN_BYTE(0xCF8) == 0x00 && IN_BYTE(0xCFA) == 0x00) { + spin_unlock_irqrestore(&pci_lock, flags); + return 1; + } + spin_unlock_irqrestore(&pci_lock, flags); + return 0; +} + /* * Probe for a cmd640 chipset, and initialize it if found. Called from ide.c */ + int __init ide_probe_for_cmd640x(void) { #ifdef CONFIG_BLK_DEV_CMD640_ENHANCED @@ -712,9 +762,9 @@ int __init ide_probe_for_cmd640x(void) bus_type = "VLB"; } else { cmd640_vlb = 0; - if (probe_for_cmd640_pci1()) + if (pci_conf1() && probe_for_cmd640_pci1()) bus_type = "PCI (type1)"; - else if (probe_for_cmd640_pci2()) + else if (pci_conf2() && probe_for_cmd640_pci2()) bus_type = "PCI (type2)"; else return 0; diff --git a/drivers/pci/access.c b/drivers/pci/access.c index 5546095e5a1f..53c08e427647 100644 --- a/drivers/pci/access.c +++ b/drivers/pci/access.c @@ -7,7 +7,7 @@ * configuration space. */ -static spinlock_t pci_lock = SPIN_LOCK_UNLOCKED; +spinlock_t pci_lock = SPIN_LOCK_UNLOCKED; /* * Wrappers for all PCI configuration access functions. They just check @@ -44,3 +44,4 @@ EXPORT_SYMBOL(pci_read_config_dword); EXPORT_SYMBOL(pci_write_config_byte); EXPORT_SYMBOL(pci_write_config_word); EXPORT_SYMBOL(pci_write_config_dword); +EXPORT_SYMBOL(pci_lock); diff --git a/drivers/pnp/pnpbios_core.c b/drivers/pnp/pnpbios_core.c index a332c3ac869f..6b8f1dde68d8 100644 --- a/drivers/pnp/pnpbios_core.c +++ b/drivers/pnp/pnpbios_core.c @@ -124,13 +124,13 @@ __asm__( ".previous \n" ); -#define Q_SET_SEL(selname, address, size) \ -set_base (gdt [(selname) >> 3], __va((u32)(address))); \ -set_limit (gdt [(selname) >> 3], size) +#define Q_SET_SEL(cpu, selname, address, size) \ +set_base(cpu_gdt_table[cpu][(selname) >> 3], __va((u32)(address))); \ +_set_limit(&cpu_gdt_table[cpu][(selname) >> 3], size) -#define Q2_SET_SEL(selname, address, size) \ -set_base (gdt [(selname) >> 3], (u32)(address)); \ -set_limit (gdt [(selname) >> 3], size) +#define Q2_SET_SEL(cpu, selname, address, size) \ +set_base(cpu_gdt_table[cpu][(selname) >> 3], (u32)(address)); \ +_set_limit((char *)&cpu_gdt_table[cpu][(selname) >> 3], size) /* * At some point we want to use this stack frame pointer to unwind @@ -161,10 +161,11 @@ static inline u16 call_pnp_bios(u16 func, u16 arg1, u16 arg2, u16 arg3, /* On some boxes IRQ's during PnP BIOS calls are deadly. */ spin_lock_irqsave(&pnp_bios_lock, flags); + /* The lock prevents us bouncing CPU here */ if (ts1_size) - Q2_SET_SEL(PNP_TS1, ts1_base, ts1_size); + Q2_SET_SEL(smp_processor_id(), PNP_TS1, ts1_base, ts1_size); if (ts2_size) - Q2_SET_SEL(PNP_TS2, ts2_base, ts2_size); + Q2_SET_SEL(smp_processor_id(), PNP_TS2, ts2_base, ts2_size); __asm__ __volatile__( "pushl %%ebp\n\t" @@ -1265,12 +1266,16 @@ int __init pnpbios_init(void) check->fields.version >> 4, check->fields.version & 15, check->fields.pm16cseg, check->fields.pm16offset, check->fields.pm16dseg); - Q2_SET_SEL(PNP_CS32, &pnp_bios_callfunc, 64 * 1024); - Q_SET_SEL(PNP_CS16, check->fields.pm16cseg, 64 * 1024); - Q_SET_SEL(PNP_DS, check->fields.pm16dseg, 64 * 1024); pnp_bios_callpoint.offset = check->fields.pm16offset; pnp_bios_callpoint.segment = PNP_CS16; pnp_bios_hdr = check; + + for(i=0; i < NR_CPUS; i++) + { + Q2_SET_SEL(i, PNP_CS32, &pnp_bios_callfunc, 64 * 1024); + Q_SET_SEL(i, PNP_CS16, check->fields.pm16cseg, 64 * 1024); + Q_SET_SEL(i, PNP_DS, check->fields.pm16dseg, 64 * 1024); + } break; } if (!pnp_bios_present()) diff --git a/fs/locks.c b/fs/locks.c index cb801127400a..3b606b44e7df 100644 --- a/fs/locks.c +++ b/fs/locks.c @@ -1242,6 +1242,9 @@ int fcntl_setlease(unsigned int fd, struct file *filp, long arg) return -EACCES; if (!S_ISREG(inode->i_mode)) return -EINVAL; + error = security_ops->file_lock(filp, arg); + if (error) + return error; lock_kernel(); @@ -1359,8 +1362,7 @@ asmlinkage long sys_flock(unsigned int fd, unsigned int cmd) if (error < 0) goto out_putf; - error = security_ops->file_lock(filp, cmd, - (cmd & LOCK_NB) ? 0 : 1); + error = security_ops->file_lock(filp, lock->fl_type); if (error) goto out_putf; @@ -1494,8 +1496,7 @@ int fcntl_setlk(struct file *filp, unsigned int cmd, struct flock *l) goto out; } - error = security_ops->file_lock(filp, file_lock->fl_type, - cmd == F_SETLKW); + error = security_ops->file_lock(filp, file_lock->fl_type); if (error) goto out; @@ -1618,8 +1619,7 @@ int fcntl_setlk64(struct file *filp, unsigned int cmd, struct flock64 *l) goto out; } - error = security_ops->file_lock(filp, file_lock->fl_type, - cmd == F_SETLKW64); + error = security_ops->file_lock(filp, file_lock->fl_type); if (error) goto out; diff --git a/fs/partitions/Config.in b/fs/partitions/Config.in index eff56b137b0a..415ac1a6c45c 100644 --- a/fs/partitions/Config.in +++ b/fs/partitions/Config.in @@ -25,7 +25,7 @@ if [ "$CONFIG_PARTITION_ADVANCED" = "y" ]; then bool ' Solaris (x86) partition table support' CONFIG_SOLARIS_X86_PARTITION bool ' Unixware slices support' CONFIG_UNIXWARE_DISKLABEL fi - dep_bool ' Windows Logical Disk Manager (Dynamic Disk) support' CONFIG_LDM_PARTITION + bool ' Windows Logical Disk Manager (Dynamic Disk) support' CONFIG_LDM_PARTITION if [ "$CONFIG_LDM_PARTITION" = "y" ]; then bool ' Windows LDM extra logging' CONFIG_LDM_DEBUG fi diff --git a/fs/partitions/msdos.c b/fs/partitions/msdos.c index 5d0bb6074fe4..61b0bc9bc02b 100644 --- a/fs/partitions/msdos.c +++ b/fs/partitions/msdos.c @@ -385,87 +385,6 @@ static struct { {SOLARIS_X86_PARTITION, parse_solaris_x86}, {0, NULL}, }; -/* - * Look for various forms of IDE disk geometry translation - */ -static int handle_ide_mess(struct block_device *bdev) -{ -#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) - Sector sect; - unsigned char *data; - kdev_t dev = to_kdev_t(bdev->bd_dev); - unsigned int sig; - int heads = 0; - struct partition *p; - int i; -#ifdef CONFIG_BLK_DEV_IDE_MODULE - if (!ide_xlate_1024) - return 1; -#endif - /* - * The i386 partition handling programs very often - * make partitions end on cylinder boundaries. - * There is no need to do so, and Linux fdisk doesn't always - * do this, and Windows NT on Alpha doesn't do this either, - * but still, this helps to guess #heads. - */ - data = read_dev_sector(bdev, 0, §); - if (!data) - return -1; - if (!msdos_magic_present(data + 510)) { - put_dev_sector(sect); - return 0; - } - sig = le16_to_cpu(*(unsigned short *)(data + 2)); - p = (struct partition *) (data + 0x1be); - for (i = 0; i < 4; i++) { - struct partition *q = &p[i]; - if (NR_SECTS(q)) { - if ((q->sector & 63) == 1 && - (q->end_sector & 63) == 63) - heads = q->end_head + 1; - break; - } - } - if (SYS_IND(p) == EZD_PARTITION) { - /* - * Accesses to sector 0 must go to sector 1 instead. - */ - if (ide_xlate_1024(dev, -1, heads, " [EZD]")) - goto reread; - } else if (SYS_IND(p) == DM6_PARTITION) { - - /* - * Everything on the disk is offset by 63 sectors, - * including a "new" MBR with its own partition table. - */ - if (ide_xlate_1024(dev, 1, heads, " [DM6:DDO]")) - goto reread; - } else if (sig <= 0x1ae && - data[sig] == 0xAA && data[sig+1] == 0x55 && - (data[sig+2] & 1)) { - /* DM6 signature in MBR, courtesy of OnTrack */ - (void) ide_xlate_1024 (dev, 0, heads, " [DM6:MBR]"); - } else if (SYS_IND(p) == DM6_AUX1PARTITION || - SYS_IND(p) == DM6_AUX3PARTITION) { - /* - * DM6 on other than the first (boot) drive - */ - (void) ide_xlate_1024(dev, 0, heads, " [DM6:AUX]"); - } else { - (void) ide_xlate_1024(dev, 2, heads, " [PTBL]"); - } - put_dev_sector(sect); - return 1; - -reread: - put_dev_sector(sect); - /* Flush the cache */ - invalidate_bdev(bdev, 1); - truncate_inode_pages(bdev->bd_inode->i_mapping, 0); -#endif /* defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) */ - return 1; -} int msdos_partition(struct parsed_partitions *state, struct block_device *bdev) { @@ -474,11 +393,7 @@ int msdos_partition(struct parsed_partitions *state, struct block_device *bdev) unsigned char *data; struct partition *p; int slot; - int err; - err = handle_ide_mess(bdev); - if (err <= 0) - return err; data = read_dev_sector(bdev, 0, §); if (!data) return -1; @@ -524,21 +439,6 @@ int msdos_partition(struct parsed_partitions *state, struct block_device *bdev) state->parts[slot].flags = 1; } - /* - * Check for old-style Disk Manager partition table - */ - if (msdos_magic_present(data + 0xfc)) { - p = (struct partition *) (0x1be + data); - for (slot = 4 ; slot < 16 ; slot++, state->next++) { - p--; - if (state->next == state->limit) - break; - if (!(START_SECT(p) && NR_SECTS(p))) - continue; - put_partition(state, state->next, - START_SECT(p), NR_SECTS(p)); - } - } printk("\n"); /* second pass - output for each on a separate line */ @@ -556,7 +456,7 @@ int msdos_partition(struct parsed_partitions *state, struct block_device *bdev) if (!subtypes[n].parse) continue; subtypes[n].parse(state, bdev, START_SECT(p)*sector_size, - NR_SECTS(p)*sector_size, n); + NR_SECTS(p)*sector_size, slot); } put_dev_sector(sect); return 1; diff --git a/include/asm-arm/arch-ebsa285/keyboard.h b/include/asm-arm/arch-ebsa285/keyboard.h index 968163b3f883..f47b43fe800c 100644 --- a/include/asm-arm/arch-ebsa285/keyboard.h +++ b/include/asm-arm/arch-ebsa285/keyboard.h @@ -6,63 +6,4 @@ * Copyright (C) 1998-2001 Russell King * (C) 1998 Phil Blundell */ -#include <linux/config.h> -#include <linux/ioport.h> -#include <asm/irq.h> -#include <asm/system.h> - -#define KEYBOARD_IRQ IRQ_ISA_KEYBOARD -#define NR_SCANCODES 128 - -#define kbd_disable_irq() do { } while (0) -#define kbd_enable_irq() do { } while (0) - -extern int pckbd_setkeycode(unsigned int scancode, unsigned int keycode); -extern int pckbd_getkeycode(unsigned int scancode); -extern int pckbd_translate(unsigned char scancode, unsigned char *keycode, - char raw_mode); -extern char pckbd_unexpected_up(unsigned char keycode); -extern void pckbd_leds(unsigned char leds); -extern void pckbd_init_hw(void); -extern unsigned char pckbd_sysrq_xlate[128]; - -static inline void kbd_init_hw(void) -{ - if (have_isa_bridge) { - k_setkeycode = pckbd_setkeycode; - k_getkeycode = pckbd_getkeycode; - k_translate = pckbd_translate; - k_unexpected_up = pckbd_unexpected_up; - k_leds = pckbd_leds; -#ifdef CONFIG_MAGIC_SYSRQ - k_sysrq_key = 0x54; - k_sysrq_xlate = pckbd_sysrq_xlate; -#endif - pckbd_init_hw(); - } -} - - -/* - * The rest of this file is to do with supporting pc_keyb.c - */ - -/* resource allocation */ -#define kbd_request_region() request_region(0x60, 16, "keyboard") -#define kbd_request_irq(handler) request_irq(KEYBOARD_IRQ, handler, 0, \ - "keyboard", NULL) - -/* How to access the keyboard macros on this platform. */ -#define kbd_read_input() inb(KBD_DATA_REG) -#define kbd_read_status() inb(KBD_STATUS_REG) -#define kbd_write_output(val) outb(val, KBD_DATA_REG) -#define kbd_write_command(val) outb(val, KBD_CNTL_REG) - -/* Some stoneage hardware needs delays after some operations. */ -#define kbd_pause() do { } while(0) - -#define aux_request_irq(hand, dev_id) \ - request_irq(AUX_IRQ, hand, SA_SHIRQ, "PS/2 Mouse", dev_id) - -#define aux_free_irq(dev_id) free_irq(AUX_IRQ, dev_id) - +#define kbd_init_hw() do { } while (0) diff --git a/include/asm-arm/arch-integrator/keyboard.h b/include/asm-arm/arch-integrator/keyboard.h index 48aab706c868..2ca4754586a9 100644 --- a/include/asm-arm/arch-integrator/keyboard.h +++ b/include/asm-arm/arch-integrator/keyboard.h @@ -17,13 +17,6 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Keyboard driver definitions for the Integrator architecture + * Now using the input subsystem... */ -#include <asm/irq.h> - -#define NR_SCANCODES 128 - -extern int kmi_kbd_init(void); - -#define kbd_disable_irq() disable_irq(IRQ_KMIINT0) -#define kbd_enable_irq() enable_irq(IRQ_KMIINT0) -#define kbd_init_hw() kmi_kbd_init() +#define kbd_init_hw() do { } while (0) diff --git a/include/asm-arm/arch-rpc/keyboard.h b/include/asm-arm/arch-rpc/keyboard.h index 8aed4bd00fba..db187f96b1cc 100644 --- a/include/asm-arm/arch-rpc/keyboard.h +++ b/include/asm-arm/arch-rpc/keyboard.h @@ -8,13 +8,6 @@ * published by the Free Software Foundation. * * Keyboard driver definitions for RiscPC architecture + * Now using the input subsystem... */ -#include <asm/irq.h> - -#define NR_SCANCODES 128 - -extern int ps2kbd_init_hw(void); - -#define kbd_disable_irq() disable_irq(IRQ_KEYBOARDRX) -#define kbd_enable_irq() enable_irq(IRQ_KEYBOARDRX) -#define kbd_init_hw() ps2kbd_init_hw() +#define kbd_init_hw() do { } while (0) diff --git a/include/asm-arm/arch-sa1100/hardware.h b/include/asm-arm/arch-sa1100/hardware.h index f12446570ffd..8a505f6c3ed3 100644 --- a/include/asm-arm/arch-sa1100/hardware.h +++ b/include/asm-arm/arch-sa1100/hardware.h @@ -13,8 +13,6 @@ #define __ASM_ARCH_HARDWARE_H #include <linux/config.h> -#include <asm/mach-types.h> - /* Flushing areas */ #define FLUSH_BASE_PHYS 0xe0000000 /* SA1100 zero bank */ diff --git a/include/asm-arm/arch-sa1100/keyboard.h b/include/asm-arm/arch-sa1100/keyboard.h index aa7f317092e5..e2a0c0196bfc 100644 --- a/include/asm-arm/arch-sa1100/keyboard.h +++ b/include/asm-arm/arch-sa1100/keyboard.h @@ -8,21 +8,13 @@ #include <linux/config.h> #include <asm/mach-types.h> -#include <asm/arch/assabet.h> -#define kbd_disable_irq() do { } while(0) -#define kbd_enable_irq() do { } while(0) - -extern int sa1111_kbd_init_hw(void); extern void gc_kbd_init_hw(void); extern void smartio_kbd_init_hw(void); extern void cerf_kbd_init_hw(void); static inline void kbd_init_hw(void) { - if ((machine_is_assabet() && machine_has_neponset()) || - machine_is_graphicsmaster()) - sa1111_kbd_init_hw(); if (machine_is_graphicsclient()) gc_kbd_init_hw(); if (machine_is_adsbitsy()) @@ -31,11 +23,6 @@ static inline void kbd_init_hw(void) if (machine_is_cerf()) cerf_kbd_init_hw(); #endif -#ifdef CONFIG_SA1100_PT_SYSTEM3 - /* TODO: add system 3 board specific functions here */ - if (machine_is_pt_system3()) - sa1111_kbd_init_hw(); -#endif } #endif /* _SA1100_KEYBOARD_H */ diff --git a/include/asm-arm/atomic.h b/include/asm-arm/atomic.h index d1b48d65ff23..ba9e4b72d821 100644 --- a/include/asm-arm/atomic.h +++ b/include/asm-arm/atomic.h @@ -36,7 +36,7 @@ static inline void atomic_add(int i, volatile atomic_t *v) { unsigned long flags; - local_save_flags_cli(flags); + local_irq_save(flags); v->counter += i; local_irq_restore(flags); } @@ -45,7 +45,7 @@ static inline void atomic_sub(int i, volatile atomic_t *v) { unsigned long flags; - local_save_flags_cli(flags); + local_irq_save(flags); v->counter -= i; local_irq_restore(flags); } @@ -54,7 +54,7 @@ static inline void atomic_inc(volatile atomic_t *v) { unsigned long flags; - local_save_flags_cli(flags); + local_irq_save(flags); v->counter += 1; local_irq_restore(flags); } @@ -63,7 +63,7 @@ static inline void atomic_dec(volatile atomic_t *v) { unsigned long flags; - local_save_flags_cli(flags); + local_irq_save(flags); v->counter -= 1; local_irq_restore(flags); } @@ -73,7 +73,7 @@ static inline int atomic_dec_and_test(volatile atomic_t *v) unsigned long flags; int val; - local_save_flags_cli(flags); + local_irq_save(flags); val = v->counter; v->counter = val -= 1; local_irq_restore(flags); @@ -86,7 +86,7 @@ static inline int atomic_add_negative(int i, volatile atomic_t *v) unsigned long flags; int val; - local_save_flags_cli(flags); + local_irq_save(flags); val = v->counter; v->counter = val += i; local_irq_restore(flags); @@ -98,7 +98,7 @@ static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr) { unsigned long flags; - local_save_flags_cli(flags); + local_irq_save(flags); *addr &= ~mask; local_irq_restore(flags); } diff --git a/include/asm-arm/hardirq.h b/include/asm-arm/hardirq.h index c96c7a390692..0e6a5492e1e4 100644 --- a/include/asm-arm/hardirq.h +++ b/include/asm-arm/hardirq.h @@ -17,27 +17,70 @@ typedef struct { #include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */ /* - * Are we in an interrupt context? Either doing bottom half - * or hardware interrupt processing? + * We put the hardirq and softirq counter into the preemption + * counter. The bitmask has the following meaning: + * + * - bits 0-7 are the preemption count (max depth: 256) + * - bits 8-15 are the softirq count (max # of softirqs: 256) + * - bits 16-23 are the hardirq count (max # of hardirqs: 256) + * - bit 26 is the PREEMPT_ACTIVE flag */ -#define in_interrupt() ({ const int __cpu = smp_processor_id(); \ - (local_irq_count(__cpu) + local_bh_count(__cpu) != 0); }) +#define PREEMPT_BITS 8 +#define SOFTIRQ_BITS 8 +#define HARDIRQ_BITS 8 -#define in_irq() (local_irq_count(smp_processor_id()) != 0) +#define PREEMPT_SHIFT 0 +#define SOFTIRQ_SHIFT (PREEMPT_SHIFT + PREEMPT_BITS) +#define HARDIRQ_SHIFT (SOFTIRQ_SHIFT + SOFTIRQ_BITS) -#ifndef CONFIG_SMP +#define __MASK(x) ((1UL << (x))-1) + +#define PREEMPT_MASK (__MASK(PREEMPT_BITS) << PREEMPT_SHIFT) +#define HARDIRQ_MASK (__MASK(HARDIRQ_BITS) << HARDIRQ_SHIFT) +#define SOFTIRQ_MASK (__MASK(SOFTIRQ_BITS) << SOFTIRQ_SHIFT) + +#define hardirq_count() (preempt_count() & HARDIRQ_MASK) +#define softirq_count() (preempt_count() & SOFTIRQ_MASK) +#define irq_count() (preempt_count() & (HARDIRQ_MASK|SOFTIRQ_MASK)) -#define hardirq_trylock(cpu) (local_irq_count(cpu) == 0) -#define hardirq_endlock(cpu) do { } while (0) +#define PREEMPT_OFFSET (1UL << PREEMPT_SHIFT) +#define SOFTIRQ_OFFSET (1UL << SOFTIRQ_SHIFT) +#define HARDIRQ_OFFSET (1UL << HARDIRQ_SHIFT) -#define irq_enter(cpu,irq) (local_irq_count(cpu)++) -#define irq_exit(cpu,irq) (local_irq_count(cpu)--) +/* + * The hardirq mask has to be large enough to have space + * for potentially all IRQ sources in the system nesting + * on a single CPU: + */ +#if (1 << HARDIRQ_BITS) < NR_IRQS +# error HARDIRQ_BITS is too low! +#endif -#define synchronize_irq() do { } while (0) -#define release_irqlock(cpu) do { } while (0) +/* + * Are we doing bottom half or hardware interrupt processing? + * Are we in a softirq context? Interrupt context? + */ +#define in_irq() (hardirq_count()) +#define in_softirq() (softirq_count()) +#define in_interrupt() (irq_count()) + +#define hardirq_trylock() (!in_interrupt()) +#define hardirq_endlock() do { } while (0) + +#define irq_enter() (preempt_count() += HARDIRQ_OFFSET) + +#ifndef CONFIG_SMP +#define irq_exit() \ + do { \ + preempt_count() -= HARDIRQ_OFFSET; \ + if (!in_interrupt() && softirq_pending(smp_processor_id())) \ + __asm__("bl%? __do_softirq": : : "lr");/* out of line */\ + preempt_enable_no_resched(); \ + } while (0) +#define synchronize_irq(irq) barrier() #else #error SMP not supported -#endif /* CONFIG_SMP */ +#endif #endif /* __ASM_HARDIRQ_H */ diff --git a/include/asm-arm/hardware/sa1111.h b/include/asm-arm/hardware/sa1111.h index a6ef00569bc6..f00889d5976c 100644 --- a/include/asm-arm/hardware/sa1111.h +++ b/include/asm-arm/hardware/sa1111.h @@ -529,120 +529,31 @@ * */ -#define _KBD( x ) _SA1111( 0x0A00 ) -#define _MSE( x ) _SA1111( 0x0C00 ) - -#define _KBDCR _SA1111( 0x0A00 ) -#define _KBDSTAT _SA1111( 0x0A04 ) -#define _KBDDATA _SA1111( 0x0A08 ) -#define _KBDCLKDIV _SA1111( 0x0A0C ) -#define _KBDPRECNT _SA1111( 0x0A10 ) -#define _MSECR _SA1111( 0x0C00 ) -#define _MSESTAT _SA1111( 0x0C04 ) -#define _MSEDATA _SA1111( 0x0C08 ) -#define _MSECLKDIV _SA1111( 0x0C0C ) -#define _MSEPRECNT _SA1111( 0x0C10 ) - -#if ( LANGUAGE == C ) - -#define KBDCR __CCREG(0x0a00) -#define KBDSTAT __CCREG(0x0a04) -#define KBDDATA __CCREG(0x0a08) -#define KBDCLKDIV __CCREG(0x0a0c) -#define KBDPRECNT __CCREG(0x0a10) -#define MSECR __CCREG(0x0c00) -#define MSESTAT __CCREG(0x0c04) -#define MSEDATA __CCREG(0x0c08) -#define MSECLKDIV __CCREG(0x0c0c) -#define MSEPRECNT __CCREG(0x0c10) - -#define KBDCR_ENA 0x08 -#define KBDCR_FKD 0x02 -#define KBDCR_FKC 0x01 - -#define KBDSTAT_TXE 0x80 -#define KBDSTAT_TXB 0x40 -#define KBDSTAT_RXF 0x20 -#define KBDSTAT_RXB 0x10 -#define KBDSTAT_ENA 0x08 -#define KBDSTAT_RXP 0x04 -#define KBDSTAT_KBD 0x02 -#define KBDSTAT_KBC 0x01 - -#define KBDCLKDIV_DivVal Fld(4,0) - -#define MSECR_ENA 0x08 -#define MSECR_FKD 0x02 -#define MSECR_FKC 0x01 - -#define MSESTAT_TXE 0x80 -#define MSESTAT_TXB 0x40 -#define MSESTAT_RXF 0x20 -#define MSESTAT_RXB 0x10 -#define MSESTAT_ENA 0x08 -#define MSESTAT_RXP 0x04 -#define MSESTAT_MSD 0x02 -#define MSESTAT_MSC 0x01 - -#define MSECLKDIV_DivVal Fld(4,0) - -#define KBDTEST1_CD 0x80 -#define KBDTEST1_RC1 0x40 -#define KBDTEST1_MC 0x20 -#define KBDTEST1_C Fld(2,3) -#define KBDTEST1_T2 0x40 -#define KBDTEST1_T1 0x20 -#define KBDTEST1_T0 0x10 -#define KBDTEST2_TICBnRES 0x08 -#define KBDTEST2_RKC 0x04 -#define KBDTEST2_RKD 0x02 -#define KBDTEST2_SEL 0x01 -#define KBDTEST3_ms_16 0x80 -#define KBDTEST3_us_64 0x40 -#define KBDTEST3_us_16 0x20 -#define KBDTEST3_DIV8 0x10 -#define KBDTEST3_DIn 0x08 -#define KBDTEST3_CIn 0x04 -#define KBDTEST3_KD 0x02 -#define KBDTEST3_KC 0x01 -#define KBDTEST4_BC12 0x80 -#define KBDTEST4_BC11 0x40 -#define KBDTEST4_TRES 0x20 -#define KBDTEST4_CLKOE 0x10 -#define KBDTEST4_CRES 0x08 -#define KBDTEST4_RXB 0x04 -#define KBDTEST4_TXB 0x02 -#define KBDTEST4_SRX 0x01 - -#define MSETEST1_CD 0x80 -#define MSETEST1_RC1 0x40 -#define MSETEST1_MC 0x20 -#define MSETEST1_C Fld(2,3) -#define MSETEST1_T2 0x40 -#define MSETEST1_T1 0x20 -#define MSETEST1_T0 0x10 -#define MSETEST2_TICBnRES 0x08 -#define MSETEST2_RKC 0x04 -#define MSETEST2_RKD 0x02 -#define MSETEST2_SEL 0x01 -#define MSETEST3_ms_16 0x80 -#define MSETEST3_us_64 0x40 -#define MSETEST3_us_16 0x20 -#define MSETEST3_DIV8 0x10 -#define MSETEST3_DIn 0x08 -#define MSETEST3_CIn 0x04 -#define MSETEST3_KD 0x02 -#define MSETEST3_KC 0x01 -#define MSETEST4_BC12 0x80 -#define MSETEST4_BC11 0x40 -#define MSETEST4_TRES 0x20 -#define MSETEST4_CLKOE 0x10 -#define MSETEST4_CRES 0x08 -#define MSETEST4_RXB 0x04 -#define MSETEST4_TXB 0x02 -#define MSETEST4_SRX 0x01 +#define SA1111_KBD 0x0a00 +#define SA1111_MSE 0x0c00 -#endif /* LANGUAGE == C */ +/* + * These are offsets from the above bases. + */ +#define SA1111_PS2CR 0x0000 +#define SA1111_PS2STAT 0x0004 +#define SA1111_PS2DATA 0x0008 +#define SA1111_PS2CLKDIV 0x000c +#define SA1111_PS2PRECNT 0x0010 + +#define PS2CR_ENA 0x08 +#define PS2CR_FKD 0x02 +#define PS2CR_FKC 0x01 + +#define PS2STAT_STP 0x0100 +#define PS2STAT_TXE 0x0080 +#define PS2STAT_TXB 0x0040 +#define PS2STAT_RXF 0x0020 +#define PS2STAT_RXB 0x0010 +#define PS2STAT_ENA 0x0008 +#define PS2STAT_RXP 0x0004 +#define PS2STAT_KBD 0x0002 +#define PS2STAT_KBC 0x0001 /* * PCMCIA Interface diff --git a/include/asm-arm/io.h b/include/asm-arm/io.h index 21ca5ae0b847..ebaef59d788a 100644 --- a/include/asm-arm/io.h +++ b/include/asm-arm/io.h @@ -29,6 +29,13 @@ #include <asm/arch/hardware.h> /* + * ISA I/O bus memory addresses are 1:1 with the physical address. + */ +#define isa_virt_to_bus virt_to_phys +#define isa_page_to_bus page_to_phys +#define isa_bus_to_virt phys_to_virt + +/* * Generic IO read/write. These perform native-endian accesses. Note * that some architectures will want to re-define __raw_{read,write}w. */ diff --git a/include/asm-arm/proc-armv/rmap.h b/include/asm-arm/proc-armv/rmap.h deleted file mode 100644 index f775d26eea88..000000000000 --- a/include/asm-arm/proc-armv/rmap.h +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef _ARMV_RMAP_H -#define _ARMV_RMAP_H -/* - * linux/include/asm-arm/proc-armv/rmap.h - * - * Architecture dependant parts of the reverse mapping code, - * - * ARM is different since hardware page tables are smaller than - * the page size and Linux uses a "duplicate" one with extra info. - * For rmap this means that the first 2 kB of a page are the hardware - * page tables and the last 2 kB are the software page tables. - */ - -static inline void pgtable_add_rmap(pte_t * ptep, struct mm_struct * mm, unsigned long address) -{ - struct page * page = virt_to_page(ptep); - - page->mm = mm; - page->index = address & ~((PTRS_PER_PTE * PAGE_SIZE) - 1); - inc_page_state(nr_page_table_pages); -} - -static inline void pgtable_remove_rmap(pte_t * ptep) -{ - struct page * page = virt_to_page(ptep); - - page->mm = NULL; - page->index = 0; - dec_page_state(nr_page_table_pages); -} - -static inline struct mm_struct * ptep_to_mm(pte_t * ptep) -{ - struct page * page = virt_to_page(ptep); - - return page->mm; -} - -/* The page table takes half of the page */ -#define PTE_MASK ((PAGE_SIZE / 2) - 1) - -static inline unsigned long ptep_to_address(pte_t * ptep) -{ - struct page * page = virt_to_page(ptep); - unsigned long low_bits; - - low_bits = ((unsigned long)ptep & PTE_MASK) * PTRS_PER_PTE; - return page->index + low_bits; -} - -#endif /* _ARMV_RMAP_H */ diff --git a/include/asm-arm/proc-armv/system.h b/include/asm-arm/proc-armv/system.h index d9647dc39f6a..e95668d52510 100644 --- a/include/asm-arm/proc-armv/system.h +++ b/include/asm-arm/proc-armv/system.h @@ -43,17 +43,23 @@ extern unsigned long cr_alignment; /* defined in entry-armv.S */ #endif /* - * A couple of speedups for the ARM + * Save the current interrupt enable state. */ +#define local_save_flags(x) \ + ({ \ + __asm__ __volatile__( \ + "mrs %0, cpsr @ local_save_flags" \ + : "=r" (x) : : "memory"); \ + }) /* * Save the current interrupt enable state & disable IRQs */ -#define local_save_flags_cli(x) \ +#define local_irq_save(x) \ ({ \ unsigned long temp; \ __asm__ __volatile__( \ - "mrs %0, cpsr @ save_flags_cli\n" \ + "mrs %0, cpsr @ local_irq_save\n" \ " orr %1, %0, #128\n" \ " msr cpsr_c, %1" \ : "=r" (x), "=r" (temp) \ @@ -64,11 +70,11 @@ extern unsigned long cr_alignment; /* defined in entry-armv.S */ /* * Enable IRQs */ -#define local_irq_enable() \ +#define local_irq_enable() \ ({ \ unsigned long temp; \ __asm__ __volatile__( \ - "mrs %0, cpsr @ sti\n" \ + "mrs %0, cpsr @ local_irq_enable\n" \ " bic %0, %0, #128\n" \ " msr cpsr_c, %0" \ : "=r" (temp) \ @@ -79,11 +85,11 @@ extern unsigned long cr_alignment; /* defined in entry-armv.S */ /* * Disable IRQs */ -#define local_irq_disable() \ +#define local_irq_disable() \ ({ \ unsigned long temp; \ __asm__ __volatile__( \ - "mrs %0, cpsr @ cli\n" \ + "mrs %0, cpsr @ local_irq_disable\n" \ " orr %0, %0, #128\n" \ " msr cpsr_c, %0" \ : "=r" (temp) \ @@ -122,21 +128,11 @@ extern unsigned long cr_alignment; /* defined in entry-armv.S */ }) /* - * save current IRQ & FIQ state - */ -#define local_save_flags(x) \ - __asm__ __volatile__( \ - "mrs %0, cpsr @ save_flags\n" \ - : "=r" (x) \ - : \ - : "memory") - -/* * restore saved IRQ & FIQ state */ #define local_irq_restore(x) \ __asm__ __volatile__( \ - "msr cpsr_c, %0 @ restore_flags\n" \ + "msr cpsr_c, %0 @ local_irq_restore\n" \ : \ : "r" (x) \ : "memory") @@ -168,14 +164,14 @@ static inline unsigned long __xchg(unsigned long x, volatile void *ptr, int size switch (size) { #ifdef swp_is_buggy case 1: - local_save_flags_cli(flags); + local_irq_save(flags); ret = *(volatile unsigned char *)ptr; *(volatile unsigned char *)ptr = x; local_irq_restore(flags); break; case 4: - local_save_flags_cli(flags); + local_irq_save(flags); ret = *(volatile unsigned long *)ptr; *(volatile unsigned long *)ptr = x; local_irq_restore(flags); diff --git a/include/asm-arm/rmap.h b/include/asm-arm/rmap.h index d79cb373829b..bb9ee93c1796 100644 --- a/include/asm-arm/rmap.h +++ b/include/asm-arm/rmap.h @@ -1,6 +1,6 @@ #ifndef _ARM_RMAP_H #define _ARM_RMAP_H -#include <asm/proc/rmap.h> +#include <asm-generic/rmap.h> #endif /* _ARM_RMAP_H */ diff --git a/include/asm-arm/softirq.h b/include/asm-arm/softirq.h index 6653175f53d8..3dfcdb13ecaf 100644 --- a/include/asm-arm/softirq.h +++ b/include/asm-arm/softirq.h @@ -1,26 +1,20 @@ #ifndef __ASM_SOFTIRQ_H #define __ASM_SOFTIRQ_H -#include <asm/atomic.h> +#include <linux/preempt.h> #include <asm/hardirq.h> -#define __cpu_bh_enable(cpu) \ - do { barrier(); local_bh_count(cpu)--; preempt_enable(); } while (0) -#define cpu_bh_disable(cpu) \ - do { preempt_disable(); local_bh_count(cpu)++; barrier(); } while (0) +#define local_bh_disable() \ + do { preempt_count() += SOFTIRQ_OFFSET; barrier(); } while (0) +#define __local_bh_enable() \ + do { barrier(); preempt_count() -= SOFTIRQ_OFFSET; } while (0) -#define local_bh_disable() cpu_bh_disable(smp_processor_id()) -#define __local_bh_enable() __cpu_bh_enable(smp_processor_id()) - -#define in_softirq() (local_bh_count(smp_processor_id()) != 0) - -#define _local_bh_enable() \ +#define local_bh_enable() \ do { \ - unsigned int *ptr = &local_bh_count(smp_processor_id()); \ - if (!--*ptr && ptr[-2]) \ + __local_bh_enable(); \ + if (unlikely(!in_interrupt() && softirq_pending(smp_processor_id()))) \ __asm__("bl%? __do_softirq": : : "lr");/* out of line */\ + preempt_check_resched(); \ } while (0) -#define local_bh_enable() do { _local_bh_enable(); preempt_enable(); } while (0) - #endif /* __ASM_SOFTIRQ_H */ diff --git a/include/asm-arm/system.h b/include/asm-arm/system.h index f110ae2eb76b..25b6975fbceb 100644 --- a/include/asm-arm/system.h +++ b/include/asm-arm/system.h @@ -64,20 +64,12 @@ extern asmlinkage void __backtrace(void); struct thread_info; extern struct task_struct *__switch_to(struct thread_info *, struct thread_info *); -#define prepare_arch_schedule(prev) do { } while(0) -#define finish_arch_schedule(prev) do { } while(0) -#define prepare_arch_switch(rq) do { } while(0) -#define finish_arch_switch(rq) spin_unlock_irq(&(rq)->lock) - #define switch_to(prev,next,last) \ do { \ __switch_to(prev->thread_info,next->thread_info); \ mb(); \ } while (0) -/* For spinlocks etc */ -#define local_irq_save(x) local_save_flags_cli(x) - #ifdef CONFIG_SMP #error SMP not supported @@ -91,12 +83,8 @@ extern struct task_struct *__switch_to(struct thread_info *, struct thread_info #define smp_rmb() barrier() #define smp_wmb() barrier() -#define cli() local_irq_disable() -#define sti() local_irq_enable() #define clf() __clf() #define stf() __stf() -#define save_flags(x) local_save_flags(x) -#define restore_flags(x) local_irq_restore(x) #endif /* CONFIG_SMP */ diff --git a/include/linux/pci.h b/include/linux/pci.h index 5099b9f382e0..c5f593251536 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -567,6 +567,8 @@ int pci_write_config_byte(struct pci_dev *dev, int where, u8 val); int pci_write_config_word(struct pci_dev *dev, int where, u16 val); int pci_write_config_dword(struct pci_dev *dev, int where, u32 val); +extern spinlock_t pci_lock; + int pci_enable_device(struct pci_dev *dev); void pci_disable_device(struct pci_dev *dev); void pci_set_master(struct pci_dev *dev); diff --git a/include/linux/security.h b/include/linux/security.h index 156e9ddce632..34fd73a0fed2 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -407,7 +407,6 @@ struct swap_info_struct; * @file contains the file structure. * @cmd contains the posix-translated lock operation to perform * (e.g. F_RDLCK, F_WRLCK). - * @blocking indicates if the request is for a blocking lock. * Return 0 if permission is granted. * @file_fcntl: * Check permission before allowing the file operation specified by @cmd @@ -753,7 +752,7 @@ struct security_operations { int (*file_mmap) (struct file * file, unsigned long prot, unsigned long flags); int (*file_mprotect) (struct vm_area_struct * vma, unsigned long prot); - int (*file_lock) (struct file * file, unsigned int cmd, int blocking); + int (*file_lock) (struct file * file, unsigned int cmd); int (*file_fcntl) (struct file * file, unsigned int cmd, unsigned long arg); int (*file_set_fowner) (struct file * file); diff --git a/include/linux/smp.h b/include/linux/smp.h index 454fdcdf14d2..df77d136f5e2 100644 --- a/include/linux/smp.h +++ b/include/linux/smp.h @@ -101,9 +101,13 @@ static inline void smp_send_reschedule_all(void) { } #define this_cpu(var) var /* Need to know about CPUs going up/down? */ -#define register_cpu_notifier(nb) 0 -#define unregister_cpu_notifier(nb) do { } while(0) - +static inline int register_cpu_notifier(struct notifier_block *nb) +{ + return 0; +} +static inline void unregister_cpu_notifier(struct notifier_block *nb) +{ +} #endif /* !SMP */ #define get_cpu() ({ preempt_disable(); smp_processor_id(); }) diff --git a/init/main.c b/init/main.c index a1c080027c3b..32cad19bf432 100644 --- a/init/main.c +++ b/init/main.c @@ -524,6 +524,19 @@ static void __init do_basic_setup(void) do_initcalls(); } +static void do_pre_smp_initcalls(void) +{ +#if CONFIG_SMP + extern int migration_init(void); +#endif + extern int spawn_ksoftirqd(void); + +#if CONFIG_SMP + migration_init(); +#endif + spawn_ksoftirqd(); +} + extern void prepare_namespace(void); static int init(void * unused) @@ -533,6 +546,9 @@ static int init(void * unused) lock_kernel(); /* Sets up cpus_possible() */ smp_prepare_cpus(max_cpus); + + do_pre_smp_initcalls(); + smp_init(); do_basic_setup(); diff --git a/kernel/sched.c b/kernel/sched.c index 67ac32a24c1f..6209d63588fc 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -16,19 +16,23 @@ * by Davide Libenzi, preemptible kernel bits by Robert Love. */ +#define __KERNEL_SYSCALLS__ + #include <linux/mm.h> #include <linux/nmi.h> #include <linux/init.h> -#include <asm/uaccess.h> +#include <linux/delay.h> +#include <linux/unistd.h> #include <linux/highmem.h> +#include <linux/security.h> +#include <linux/notifier.h> #include <linux/smp_lock.h> -#include <asm/mmu_context.h> #include <linux/interrupt.h> #include <linux/completion.h> #include <linux/kernel_stat.h> -#include <linux/security.h> -#include <linux/notifier.h> -#include <linux/delay.h> + +#include <asm/uaccess.h> +#include <asm/mmu_context.h> /* * Convert user-nice values [ -20 ... 0 ... 19 ] @@ -1816,18 +1820,57 @@ out: preempt_enable(); } +/* + * The migration thread startup relies on the following property + * of set_cpus_allowed(): if the thread is not running currently + * then we can just put it into the target runqueue. + */ +DECLARE_MUTEX_LOCKED(migration_startup); + +typedef struct migration_startup_data { + int cpu; + task_t *thread; +} migration_startup_t; + +static int migration_startup_thread(void * data) +{ + migration_startup_t *startup = data; + + wait_task_inactive(startup->thread); + set_cpus_allowed(startup->thread, 1UL << startup->cpu); + up(&migration_startup); + + return 0; +} + static int migration_thread(void * bind_cpu) { int cpu = (int) (long) bind_cpu; struct sched_param param = { sched_priority: MAX_RT_PRIO-1 }; + migration_startup_t startup; runqueue_t *rq; - int ret; + int ret, pid; daemonize(); sigfillset(¤t->blocked); set_fs(KERNEL_DS); - set_cpus_allowed(current, 1UL << cpu); + startup.cpu = cpu; + startup.thread = current; + pid = kernel_thread(migration_startup_thread, &startup, + CLONE_FS | CLONE_FILES | CLONE_SIGNAL); + down(&migration_startup); + + /* we need to waitpid() to release the helper thread */ + waitpid(pid, NULL, __WCLONE); + + /* + * At this point the startup helper thread must have + * migrated us to the proper CPU already: + */ + if (smp_processor_id() != (int)bind_cpu) + BUG(); + printk("migration_task %d on cpu=%d\n", cpu, smp_processor_id()); ret = setscheduler(0, SCHED_FIFO, ¶m); @@ -1888,12 +1931,15 @@ static int migration_call(struct notifier_block *nfb, unsigned long action, void *hcpu) { + unsigned long cpu = (unsigned long)hcpu; + switch (action) { case CPU_ONLINE: - printk("Starting migration thread for cpu %li\n", - (long)hcpu); - kernel_thread(migration_thread, hcpu, + printk("Starting migration thread for cpu %li\n", cpu); + kernel_thread(migration_thread, (void *)cpu, CLONE_FS | CLONE_FILES | CLONE_SIGNAL); + while (!cpu_rq(cpu)->migration_thread) + yield(); break; } return NOTIFY_OK; @@ -1901,7 +1947,7 @@ static int migration_call(struct notifier_block *nfb, static struct notifier_block migration_notifier = { &migration_call, NULL, 0 }; -int __init migration_init(void) +__init int migration_init(void) { /* Start one for boot CPU. */ migration_call(&migration_notifier, CPU_ONLINE, @@ -1910,7 +1956,6 @@ int __init migration_init(void) return 0; } -__initcall(migration_init); #endif extern void init_timervecs(void); diff --git a/kernel/softirq.c b/kernel/softirq.c index 38ae82b344c0..4f606e1acbd9 100644 --- a/kernel/softirq.c +++ b/kernel/softirq.c @@ -410,11 +410,9 @@ static int __devinit cpu_callback(struct notifier_block *nfb, static struct notifier_block cpu_nfb = { &cpu_callback, NULL, 0 }; -static __init int spawn_ksoftirqd(void) +__init int spawn_ksoftirqd(void) { cpu_callback(&cpu_nfb, CPU_ONLINE, (void *)smp_processor_id()); register_cpu_notifier(&cpu_nfb); return 0; } - -__initcall(spawn_ksoftirqd); diff --git a/sound/oss/cs46xx.c b/sound/oss/cs46xx.c index 632a24b0a32b..202aeb159559 100644 --- a/sound/oss/cs46xx.c +++ b/sound/oss/cs46xx.c @@ -2521,7 +2521,7 @@ static int cs_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un { dmabuf = &state->dmabuf; stop_dac(state); - synchronize_irq(); + synchronize_irq(card->irq); dmabuf->ready = 0; resync_dma_ptrs(state); dmabuf->swptr = dmabuf->hwptr = 0; @@ -2536,7 +2536,7 @@ static int cs_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un { dmabuf = &state->dmabuf; stop_adc(state); - synchronize_irq(); + synchronize_irq(card->irq); resync_dma_ptrs(state); dmabuf->ready = 0; dmabuf->swptr = dmabuf->hwptr = 0; |
