Commit d45db7c2 authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://bkbits.ras.ucalgary.ca/rgooch-2.5

into home.transmeta.com:/home/torvalds/v2.5/linux
parents ddef8ca8 13243cc5
...@@ -237,7 +237,7 @@ __syscall_start: ...@@ -237,7 +237,7 @@ __syscall_start:
/* 220 */ .long sys_madvise /* 220 */ .long sys_madvise
.long sys_fcntl64 .long sys_fcntl64
.long sys_ni_syscall /* TUX */ .long sys_ni_syscall /* TUX */
.long sys_ni_syscall /* Security */ .long sys_security
.long sys_gettid .long sys_gettid
/* 225 */ .long sys_readahead /* 225 */ .long sys_readahead
.long sys_setxattr .long sys_setxattr
......
...@@ -725,7 +725,7 @@ __dabt_svc: sub sp, sp, #S_FRAME_SIZE ...@@ -725,7 +725,7 @@ __dabt_svc: sub sp, sp, #S_FRAME_SIZE
msr cpsr_c, r9 msr cpsr_c, r9
mov r2, sp mov r2, sp
bl do_DataAbort bl do_DataAbort
set_cpsr_c r0, #PSR_I_BIT | MODE_SVC disable_irq r0
ldr r0, [sp, #S_PSR] ldr r0, [sp, #S_PSR]
msr spsr, r0 msr spsr, r0
ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr
...@@ -776,9 +776,9 @@ svc_preempt: teq r9, #0 @ was preempt count = 0 ...@@ -776,9 +776,9 @@ svc_preempt: teq r9, #0 @ was preempt count = 0
movne pc, lr movne pc, lr
mov r7, #PREEMPT_ACTIVE mov r7, #PREEMPT_ACTIVE
str r7, [r8, #TI_PREEMPT] @ set 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 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 ldr r0, [r8, #TI_FLAGS] @ get new tasks TI_FLAGS
tst r0, #_TIF_NEED_RESCHED tst r0, #_TIF_NEED_RESCHED
beq preempt_return @ go again beq preempt_return @ go again
...@@ -801,7 +801,7 @@ __und_svc: sub sp, sp, #S_FRAME_SIZE ...@@ -801,7 +801,7 @@ __und_svc: sub sp, sp, #S_FRAME_SIZE
mov r0, sp @ struct pt_regs *regs mov r0, sp @ struct pt_regs *regs
bl do_undefinstr 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 ldr lr, [sp, #S_PSR] @ Get SVC cpsr
msr spsr, lr msr spsr, lr
ldmia sp, {r0 - pc}^ @ Restore SVC registers ldmia sp, {r0 - pc}^ @ Restore SVC registers
...@@ -822,7 +822,7 @@ __pabt_svc: sub sp, sp, #S_FRAME_SIZE ...@@ -822,7 +822,7 @@ __pabt_svc: sub sp, sp, #S_FRAME_SIZE
mov r0, r2 @ address (pc) mov r0, r2 @ address (pc)
mov r1, sp @ regs mov r1, sp @ regs
bl do_PrefetchAbort @ call abort handler bl do_PrefetchAbort @ call abort handler
set_cpsr_c r0, #PSR_I_BIT | MODE_SVC disable_irq r0
ldr r0, [sp, #S_PSR] ldr r0, [sp, #S_PSR]
msr spsr, r0 msr spsr, r0
ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr 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 ...@@ -861,7 +861,7 @@ __dabt_usr: sub sp, sp, #S_FRAME_SIZE @ Allocate frame size in one go
#else #else
bl CPU_ABORT_HANDLER bl CPU_ABORT_HANDLER
#endif #endif
set_cpsr_c r2, #MODE_SVC @ Enable interrupts enable_irq r2 @ Enable interrupts
mov r2, sp mov r2, sp
adrsvc al, lr, ret_from_exception adrsvc al, lr, ret_from_exception
b do_DataAbort b do_DataAbort
...@@ -916,7 +916,7 @@ __und_usr: sub sp, sp, #S_FRAME_SIZE @ Allocate frame size in one go ...@@ -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, r9, ret_from_exception @ r9 = normal FP return
adrsvc al, lr, fpundefinstr @ lr = undefined instr 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 get_thread_info r10 @ get current thread
ldr r4, [r10, #TI_TASK] @ get current task ldr r4, [r10, #TI_TASK] @ get current task
mov r8, #1 mov r8, #1
...@@ -939,7 +939,7 @@ __pabt_usr: sub sp, sp, #S_FRAME_SIZE @ Allocate frame size in one go ...@@ -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 stmdb r8, {sp, lr}^ @ Save sp_usr lr_usr
alignment_trap r4, r7, __temp_abt alignment_trap r4, r7, __temp_abt
zero_fp zero_fp
set_cpsr_c r0, #MODE_SVC @ Enable interrupts enable_irq r0 @ Enable interrupts
mov r0, r5 @ address (pc) mov r0, r5 @ address (pc)
mov r1, sp @ regs mov r1, sp @ regs
bl do_PrefetchAbort @ call abort handler bl do_PrefetchAbort @ call abort handler
......
...@@ -35,18 +35,27 @@ ENTRY(__do_softirq) ...@@ -35,18 +35,27 @@ ENTRY(__do_softirq)
* stack. * stack.
*/ */
ret_fast_syscall: ret_fast_syscall:
set_cpsr_c r1, #PSR_I_BIT | MODE_SVC @ disable interrupts disable_irq r1 @ disable interrupts
ldr r1, [tsk, #TI_FLAGS] ldr r1, [tsk, #TI_FLAGS]
tst r1, #_TIF_WORK_MASK tst r1, #_TIF_WORK_MASK
bne ret_fast_work bne fast_work_pending
fast_restore_user_regs fast_restore_user_regs
/* /*
* Ok, we need to do extra processing, enter the slow path. * Ok, we need to do extra processing, enter the slow path.
*/ */
ret_fast_work: fast_work_pending:
str r0, [sp, #S_R0+S_OFF]! @ returned r0 str r0, [sp, #S_R0+S_OFF]! @ returned r0
b work_pending 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: work_resched:
bl schedule bl schedule
...@@ -55,22 +64,12 @@ work_resched: ...@@ -55,22 +64,12 @@ work_resched:
*/ */
ENTRY(ret_to_user) ENTRY(ret_to_user)
ret_slow_syscall: ret_slow_syscall:
set_cpsr_c r1, #PSR_I_BIT | MODE_SVC @ disable interrupts disable_irq r1 @ disable interrupts
ldr r1, [tsk, #TI_FLAGS] ldr r1, [tsk, #TI_FLAGS]
tst r1, #_TIF_WORK_MASK tst r1, #_TIF_WORK_MASK
beq no_work_pending bne work_pending
work_pending:
tst r1, #_TIF_NEED_RESCHED
bne work_resched
tst r1, #_TIF_NOTIFY_RESUME | _TIF_SIGPENDING
blne __do_notify_resume
no_work_pending: no_work_pending:
restore_user_regs slow_restore_user_regs
__do_notify_resume:
mov r0, sp @ 'regs'
mov r2, why @ 'syscall'
b do_notify_resume @ note the bl above sets lr
/* /*
* This is how we return from a fork. * This is how we return from a fork.
...@@ -80,9 +79,9 @@ ENTRY(ret_from_fork) ...@@ -80,9 +79,9 @@ ENTRY(ret_from_fork)
bl schedule_tail bl schedule_tail
#endif #endif
get_thread_info tsk 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 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 beq ret_slow_syscall
mov r1, sp mov r1, sp
mov r0, #1 @ trace exit [IP = 1] mov r0, #1 @ trace exit [IP = 1]
...@@ -134,7 +133,7 @@ ENTRY(vector_swi) ...@@ -134,7 +133,7 @@ ENTRY(vector_swi)
ldr ip, [ip] ldr ip, [ip]
mcr p15, 0, ip, c1, c0 @ update control register mcr p15, 0, ip, c1, c0 @ update control register
#endif #endif
enable_irqs ip enable_irq ip
str r4, [sp, #-S_OFF]! @ push fifth arg str r4, [sp, #-S_OFF]! @ push fifth arg
......
...@@ -69,6 +69,25 @@ ...@@ -69,6 +69,25 @@
#define S_OFF 8 #define S_OFF 8
#ifdef CONFIG_CPU_32 #ifdef CONFIG_CPU_32
.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 .macro save_user_regs
sub sp, sp, #S_FRAME_SIZE sub sp, sp, #S_FRAME_SIZE
stmia sp, {r0 - r12} @ Calling r0 - r12 stmia sp, {r0 - r12} @ Calling r0 - r12
...@@ -81,20 +100,20 @@ ...@@ -81,20 +100,20 @@
.endm .endm
.macro restore_user_regs .macro restore_user_regs
ldr r0, [sp, #S_PSR] @ Get calling cpsr ldr r1, [sp, #S_PSR] @ Get calling cpsr
mov ip, #PSR_I_BIT | MODE_SVC disable_irq ip @ disable IRQs
msr cpsr_c, ip @ disable IRQs ldr lr, [sp, #S_PC]! @ Get PC
msr spsr, r0 @ save in spsr_svc msr spsr, r1 @ save in spsr_svc
ldr lr, [sp, #S_PC] @ Get PC ldmdb sp, {r0 - lr}^ @ Get calling r0 - lr
ldmia sp, {r0 - lr}^ @ Get calling r0 - lr
mov r0, r0 mov r0, r0
add sp, sp, #S_FRAME_SIZE add sp, sp, #S_FRAME_SIZE - S_PC
movs pc, lr @ return & move spsr_svc into cpsr movs pc, lr @ return & move spsr_svc into cpsr
.endm .endm
/*
* Must be called with IRQs already disabled.
*/
.macro fast_restore_user_regs .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 r1, [sp, #S_OFF + S_PSR] @ get calling cpsr
ldr lr, [sp, #S_OFF + S_PC]! @ get pc ldr lr, [sp, #S_OFF + S_PC]! @ get pc
msr spsr, r1 @ save in spsr_svc msr spsr, r1 @ save in spsr_svc
...@@ -104,12 +123,20 @@ ...@@ -104,12 +123,20 @@
movs pc, lr @ return & move spsr_svc into cpsr movs pc, lr @ return & move spsr_svc into cpsr
.endm .endm
.macro mask_pc, rd, rm /*
* 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 .endm
.macro enable_irqs, temp .macro mask_pc, rd, rm
mov \temp, #MODE_SVC
msr cpsr_c, \temp
.endm .endm
.macro get_thread_info, rd .macro get_thread_info, rd
...@@ -117,7 +144,7 @@ ...@@ -117,7 +144,7 @@
mov \rd, \rd, lsl #13 mov \rd, \rd, lsl #13
.endm .endm
/* /*
* Like adr, but force SVC mode (if required) * Like adr, but force SVC mode (if required)
*/ */
.macro adrsvc, cond, reg, label .macro adrsvc, cond, reg, label
...@@ -215,13 +242,3 @@ tsk .req r9 @ current thread_info ...@@ -215,13 +242,3 @@ tsk .req r9 @ current thread_info
ldr scno, [lr, #-4] @ get SWI instruction ldr scno, [lr, #-4] @ get SWI instruction
#endif #endif
.endm .endm
.macro set_cpsr_c, reg, mode
#if 1
mov \reg, \mode
msr cpsr_c, \reg
#else
msr cpsr_c, \mode
#endif
.endm
...@@ -217,14 +217,14 @@ do_simple_IRQ(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs) ...@@ -217,14 +217,14 @@ do_simple_IRQ(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
desc->triggered = 1; desc->triggered = 1;
irq_enter(cpu, irq); irq_enter();
kstat.irqs[cpu][irq]++; kstat.irqs[cpu][irq]++;
action = desc->action; action = desc->action;
if (action) if (action)
__do_irq(irq, desc->action, regs); __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) ...@@ -256,7 +256,7 @@ do_edge_IRQ(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
*/ */
desc->running = 1; desc->running = 1;
irq_enter(cpu, irq); irq_enter();
kstat.irqs[cpu][irq]++; kstat.irqs[cpu][irq]++;
do { do {
...@@ -274,7 +274,7 @@ do_edge_IRQ(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs) ...@@ -274,7 +274,7 @@ do_edge_IRQ(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
__do_irq(irq, action, regs); __do_irq(irq, action, regs);
} while (desc->pending); } while (desc->pending);
irq_exit(cpu, irq); irq_exit();
desc->running = 0; desc->running = 0;
...@@ -311,7 +311,7 @@ do_level_IRQ(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs) ...@@ -311,7 +311,7 @@ do_level_IRQ(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
desc->chip->ack(irq); desc->chip->ack(irq);
if (likely(desc->enabled)) { if (likely(desc->enabled)) {
irq_enter(cpu, irq); irq_enter();
kstat.irqs[cpu][irq]++; kstat.irqs[cpu][irq]++;
/* /*
...@@ -325,7 +325,7 @@ do_level_IRQ(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs) ...@@ -325,7 +325,7 @@ do_level_IRQ(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
!check_irq_lock(desc, irq, regs))) !check_irq_lock(desc, irq, regs)))
desc->chip->unmask(irq); desc->chip->unmask(irq);
} }
irq_exit(cpu, irq); irq_exit();
} }
} }
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
#include <linux/ptrace.h> #include <linux/ptrace.h>
#include <linux/user.h> #include <linux/user.h>
#include <linux/security.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/pgtable.h> #include <asm/pgtable.h>
...@@ -655,6 +656,9 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) ...@@ -655,6 +656,9 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
/* are we already being traced? */ /* are we already being traced? */
if (current->ptrace & PT_PTRACED) if (current->ptrace & PT_PTRACED)
goto out; goto out;
ret = security_ops->ptrace(current->parent, current);
if (ret)
goto out;
/* set the ptrace bit in the process flags. */ /* set the ptrace bit in the process flags. */
current->ptrace |= PT_PTRACED; current->ptrace |= PT_PTRACED;
ret = 0; ret = 0;
......
#include <linux/config.h> #include <linux/config.h>
#include <linux/kd.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); * Translation of escaped scancodes to keycodes.
int (*k_translate)(unsigned char, unsigned char *, char); * This is now user-settable.
char (*k_unexpected_up)(unsigned char); * 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); void (*k_leds)(unsigned char);
/* Simple translation table for the SysRq keys */
#ifdef CONFIG_MAGIC_SYSRQ #ifdef CONFIG_MAGIC_SYSRQ
int k_sysrq_key; static unsigned char gen_sysrq_xlate[128] =
unsigned char *k_sysrq_xlate; "\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 #endif
/* /*
* linux/arch/arm/mach-integrator/cpu.c * 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 * 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 * it under the terms of the GNU General Public License version 2 as
...@@ -15,6 +15,9 @@ ...@@ -15,6 +15,9 @@
#include <linux/types.h> #include <linux/types.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/cpufreq.h> #include <linux/cpufreq.h>
#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/smp.h>
#include <linux/init.h> #include <linux/init.h>
#include <asm/hardware.h> #include <asm/hardware.h>
...@@ -42,7 +45,7 @@ static unsigned int vco_to_freq(struct vco vco, int factor) ...@@ -42,7 +45,7 @@ static unsigned int vco_to_freq(struct vco vco, int factor)
#ifdef CONFIG_CPU_FREQ #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 }; 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) ...@@ -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 * Validate the speed in khz. If it is outside our
* range, then return the lowest. * 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; struct vco vco;
...@@ -87,11 +91,21 @@ unsigned int integrator_validatespeed(unsigned int freq_khz) ...@@ -87,11 +91,21 @@ unsigned int integrator_validatespeed(unsigned int freq_khz)
return vco_to_freq(vco, 1); 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); struct vco vco = freq_to_vco(freq_khz, 1);
unsigned long cpus_allowed;
u_int cm_osc; 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 = __raw_readl(CM_OSC);
cm_osc &= 0xfffff800; cm_osc &= 0xfffff800;
cm_osc |= vco.vdw | vco.od << 8; cm_osc |= vco.vdw | vco.od << 8;
...@@ -99,44 +113,72 @@ void integrator_setspeed(unsigned int freq_khz) ...@@ -99,44 +113,72 @@ void integrator_setspeed(unsigned int freq_khz)
__raw_writel(0xa05f, CM_LOCK); __raw_writel(0xa05f, CM_LOCK);
__raw_writel(cm_osc, CM_OSC); __raw_writel(cm_osc, CM_OSC);
__raw_writel(0, CM_LOCK); __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 #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 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;
}
cpus_allowed = current->cpus_allowed;
for (cpu = 0; cpu < NR_CPUS; cpu++) {
u_int cm_osc, cm_stat, mem_freq_khz;
struct vco vco; struct vco vco;
cm_osc = __raw_readl(CM_OSC); if (!cpu_online(cpu))
continue;
set_cpus_allowed(current, 1 << cpu);
BUG_ON(cpu != smp_processor_id());
cm_stat = __raw_readl(CM_STAT);
cm_osc = __raw_readl(CM_OSC);
vco.od = (cm_osc >> 20) & 7; vco.od = (cm_osc >> 20) & 7;
vco.vdw = (cm_osc >> 12) & 255; vco.vdw = (cm_osc >> 12) & 255;
mem_freq_khz = vco_to_freq(vco, 2); mem_freq_khz = vco_to_freq(vco, 2);
printk(KERN_INFO "Memory clock = %d.%03d MHz\n", printk(KERN_INFO "CPU%d: Module id: %d\n", cpu, cm_stat & 255);
mem_freq_khz / 1000, mem_freq_khz % 1000); 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.od = (cm_osc >> 8) & 7;
vco.vdw = cm_osc & 255; vco.vdw = cm_osc & 255;
cpu_freq_khz = vco_to_freq(vco, 1);
#ifdef CONFIG_CPU_FREQ freqs[cpu].min = 12000;
{ freqs[cpu].max = 160000;
struct cpufreq_driver cpufreq_driver; freqs[cpu].cur = vco_to_freq(vco, 1);
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);
} }
#endif
cm_stat = __raw_readl(CM_STAT); set_cpus_allowed(current, cpus_allowed);
printk("Module id: %d\n", cm_stat & 255);
#ifdef CONFIG_CPU_FREQ
integrator_driver.freq = freqs;
cpufreq_register(&integrator_driver);
#else
kfree(freqs);
#endif
return 0; return 0;
} }
__initcall(cpu_init); __initcall(integrator_cpu_init);
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include <linux/serial_core.h> #include <linux/serial_core.h>
#include <asm/hardware.h> #include <asm/hardware.h>
#include <asm/mach-types.h>
#include <asm/setup.h> #include <asm/setup.h>
#include <asm/irq.h> #include <asm/irq.h>
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include <linux/serial_core.h> #include <linux/serial_core.h>
#include <asm/hardware.h> #include <asm/hardware.h>
#include <asm/mach-types.h>
#include <asm/irq.h> #include <asm/irq.h>
#include <asm/setup.h> #include <asm/setup.h>
#include <asm/page.h> #include <asm/page.h>
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include <linux/errno.h> #include <linux/errno.h>
#include <asm/hardware.h> #include <asm/hardware.h>
#include <asm/mach-types.h>
#include <asm/setup.h> #include <asm/setup.h>
#include <asm/arch/irqs.h> #include <asm/arch/irqs.h>
......
...@@ -91,7 +91,7 @@ ...@@ -91,7 +91,7 @@
#include <asm/hardware.h> #include <asm/hardware.h>
extern unsigned int sa11x0_freq_to_ppcr(unsigned int khz); 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); extern unsigned int sa11x0_getspeed(void);
typedef struct { typedef struct {
...@@ -220,29 +220,35 @@ static struct notifier_block sa1100_dram_block = { ...@@ -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); 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) static int __init sa1100_dram_init(void)
{ {
int ret = -ENODEV; int ret = -ENODEV;
if ((processor_id & CPU_SA1100_MASK) == CPU_SA1100_ID) { if ((processor_id & CPU_SA1100_MASK) == CPU_SA1100_ID) {
cpufreq_driver_t cpufreq_driver;
ret = cpufreq_register_notifier(&sa1100_dram_block); ret = cpufreq_register_notifier(&sa1100_dram_block);
if (ret) if (ret)
return ret; return ret;
cpufreq_driver.freq.min = 59000; sa1100_freqs.cur = sa11x0_getspeed();
cpufreq_driver.freq.max = 287000;
cpufreq_driver.freq.cur = sa11x0_getspeed();
cpufreq_driver.validate = &sa11x0_validatespeed;
cpufreq_driver.setspeed = &sa1100_setspeed;
ret = cpufreq_register(cpufreq_driver);< ret = cpufreq_register(&sa1100_driver);
} }
return ret; return ret;
......
...@@ -24,13 +24,14 @@ ...@@ -24,13 +24,14 @@
#include <linux/init.h> #include <linux/init.h>
#include <asm/hardware.h> #include <asm/hardware.h>
#include <asm/mach-types.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/system.h> #include <asm/system.h>
#undef DEBUG #undef DEBUG
extern unsigned int sa11x0_freq_to_ppcr(unsigned int khz); 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); extern unsigned int sa11x0_getspeed(void);
struct sdram_params { struct sdram_params {
...@@ -213,7 +214,7 @@ sdram_update_refresh(u_int cpu_khz, struct sdram_params *sdram) ...@@ -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 * 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. * 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_params *sdram = &sdram_params;
struct sdram_info sd; struct sdram_info sd;
...@@ -284,6 +285,18 @@ static void sa1110_setspeed(unsigned int khz) ...@@ -284,6 +285,18 @@ static void sa1110_setspeed(unsigned int khz)
sdram_update_refresh(khz, sdram); 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) static int __init sa1110_clk_init(void)
{ {
struct sdram_params *sdram = NULL; struct sdram_params *sdram = NULL;
...@@ -298,8 +311,6 @@ static int __init sa1110_clk_init(void) ...@@ -298,8 +311,6 @@ static int __init sa1110_clk_init(void)
sdram = &samsung_km416s4030ct; sdram = &samsung_km416s4030ct;
if (sdram) { if (sdram) {
struct cpufreq_driver cpufreq_driver;
printk(KERN_DEBUG "SDRAM: tck: %d trcd: %d trp: %d" printk(KERN_DEBUG "SDRAM: tck: %d trcd: %d trp: %d"
" twr: %d refresh: %d cas_latency: %d\n", " twr: %d refresh: %d cas_latency: %d\n",
sdram->tck, sdram->trcd, sdram->trp, sdram->tck, sdram->trcd, sdram->trp,
...@@ -307,15 +318,10 @@ static int __init sa1110_clk_init(void) ...@@ -307,15 +318,10 @@ static int __init sa1110_clk_init(void)
memcpy(&sdram_params, sdram, sizeof(sdram_params)); memcpy(&sdram_params, sdram, sizeof(sdram_params));
sa1110_setspeed(sa11x0_getspeed()); sa1110_freqs.cur = sa11x0_getspeed();
sa1110_setspeed(0, sa1110_freqs.cur);
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;
return cpufreq_register(cpufreq_driver); return cpufreq_register(&sa1110_driver);
} }
return 0; return 0;
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include <linux/tty.h> #include <linux/tty.h>
#include <asm/hardware.h> #include <asm/hardware.h>
#include <asm/mach-types.h>
#include <asm/setup.h> #include <asm/setup.h>
#include <asm/mach/arch.h> #include <asm/mach/arch.h>
......
...@@ -71,7 +71,7 @@ unsigned int sa11x0_freq_to_ppcr(unsigned int khz) ...@@ -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 * Validate the speed in khz. If we can't generate the precise
* frequency requested, round it down (to be on the safe side). * 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; return cclk_frequency_100khz[sa11x0_freq_to_ppcr(khz)] * 100;
} }
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include <linux/ioport.h> #include <linux/ioport.h>
#include <asm/hardware.h> #include <asm/hardware.h>
#include <asm/mach-types.h>
#include <asm/setup.h> #include <asm/setup.h>
#include <asm/irq.h> #include <asm/irq.h>
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include <asm/irq.h> #include <asm/irq.h>
#include <asm/hardware.h> #include <asm/hardware.h>
#include <asm/mach-types.h>
#include <asm/setup.h> #include <asm/setup.h>
#include <asm/mach/arch.h> #include <asm/mach/arch.h>
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <linux/tty.h> #include <linux/tty.h>
#include <asm/hardware.h> #include <asm/hardware.h>
#include <asm/mach-types.h>
#include <asm/setup.h> #include <asm/setup.h>
#include <asm/mach/arch.h> #include <asm/mach/arch.h>
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include <linux/device.h> #include <linux/device.h>
#include <asm/hardware.h> #include <asm/hardware.h>
#include <asm/mach-types.h>
#include <asm/irq.h> #include <asm/irq.h>
#include <asm/mach/map.h> #include <asm/mach/map.h>
#include <asm/mach/irq.h> #include <asm/mach/irq.h>
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <linux/tty.h> #include <linux/tty.h>
#include <asm/hardware.h> #include <asm/hardware.h>
#include <asm/mach-types.h>
#include <asm/setup.h> #include <asm/setup.h>
#include <asm/mach/arch.h> #include <asm/mach/arch.h>
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include <linux/ioport.h> #include <linux/ioport.h>
#include <asm/hardware.h> #include <asm/hardware.h>
#include <asm/mach-types.h>
#include <asm/setup.h> #include <asm/setup.h>
#include <asm/mach/arch.h> #include <asm/mach/arch.h>
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <asm/hardware.h> #include <asm/hardware.h>
#include <asm/mach-types.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/irq.h> #include <asm/irq.h>
#include <asm/mach/irq.h> #include <asm/mach/irq.h>
......
...@@ -44,9 +44,8 @@ ...@@ -44,9 +44,8 @@
#include <linux/cpufreq.h> #include <linux/cpufreq.h>
#include <asm/hardware.h> #include <asm/hardware.h>
#include <asm/mach-types.h>
#include <asm/setup.h> #include <asm/setup.h>
#include <asm/page.h>
#include <asm/pgtable.h>
#include <asm/irq.h> #include <asm/irq.h>
#include <asm/mach/arch.h> #include <asm/mach/arch.h>
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <linux/tty.h> #include <linux/tty.h>
#include <asm/hardware.h> #include <asm/hardware.h>
#include <asm/mach-types.h>
#include <asm/setup.h> #include <asm/setup.h>
#include <asm/mach/arch.h> #include <asm/mach/arch.h>
......
...@@ -399,13 +399,13 @@ do_alignment_ldmstm(unsigned long addr, unsigned long instr, struct pt_regs *reg ...@@ -399,13 +399,13 @@ do_alignment_ldmstm(unsigned long addr, unsigned long instr, struct pt_regs *reg
eaddr += 4; 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 * the FSR (and hence addr) equal to the updated base address
* of the multiple access rather than the restored value. * 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! * [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 * This is a "hint" - we already have eaddr worked out by the
* processor for us. * processor for us.
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include <asm/pgtable.h> #include <asm/pgtable.h>
#include <asm/pgalloc.h> #include <asm/pgalloc.h>
#include <asm/page.h> #include <asm/page.h>
#include <asm/rmap.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/setup.h> #include <asm/setup.h>
...@@ -149,6 +150,7 @@ void free_pgd_slow(pgd_t *pgd) ...@@ -149,6 +150,7 @@ void free_pgd_slow(pgd_t *pgd)
pte = pmd_page(*pmd); pte = pmd_page(*pmd);
pmd_clear(pmd); pmd_clear(pmd);
pgtable_remove_rmap(pte);
pte_free(pte); pte_free(pte);
pmd_free(pmd); pmd_free(pmd);
free: free:
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
# To add an entry into this database, please see Documentation/arm/README, # To add an entry into this database, please see Documentation/arm/README,
# or contact rmk@arm.linux.org.uk # 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 # machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number
# #
...@@ -175,7 +175,7 @@ amico ARCH_AMICO AMICO 163 ...@@ -175,7 +175,7 @@ amico ARCH_AMICO AMICO 163
iam SA1100_IAM IAM 164 iam SA1100_IAM IAM 164
tt530 SA1100_TT530 TT530 165 tt530 SA1100_TT530 TT530 165
sam2400 ARCH_SAM2400 SAM2400 166 sam2400 ARCH_SAM2400 SAM2400 166
jornada56x ARCH_JORNADA56X JORNADA56X 167 jornada56x SA1100_JORNADA56X JORNADA56X 167
active SA1100_ACTIVE ACTIVE 168 active SA1100_ACTIVE ACTIVE 168
iq80321 ARCH_IQ80321 IQ80321 169 iq80321 ARCH_IQ80321 IQ80321 169
wid SA1100_WID WID 170 wid SA1100_WID WID 170
...@@ -207,3 +207,10 @@ nexio SA1100_NEXIO NEXIO 195 ...@@ -207,3 +207,10 @@ nexio SA1100_NEXIO NEXIO 195
bitbox SA1100_BITBOX BITBOX 196 bitbox SA1100_BITBOX BITBOX 196
g200 SA1100_G200 G200 197 g200 SA1100_G200 G200 197
gill SA1100_GILL GILL 198 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
...@@ -38,7 +38,8 @@ spinlock_t i8259A_lock = SPIN_LOCK_UNLOCKED; ...@@ -38,7 +38,8 @@ spinlock_t i8259A_lock = SPIN_LOCK_UNLOCKED;
static void end_8259A_irq (unsigned int irq) 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); enable_8259A_irq(irq);
} }
......
...@@ -187,10 +187,6 @@ int show_interrupts(struct seq_file *p, void *v) ...@@ -187,10 +187,6 @@ int show_interrupts(struct seq_file *p, void *v)
#if CONFIG_SMP #if CONFIG_SMP
inline void synchronize_irq(unsigned int irq) 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) while (irq_desc[irq].status & IRQ_INPROGRESS)
cpu_relax(); cpu_relax();
} }
...@@ -350,7 +346,7 @@ asmlinkage unsigned int do_IRQ(struct pt_regs regs) ...@@ -350,7 +346,7 @@ asmlinkage unsigned int do_IRQ(struct pt_regs regs)
* use the action we have. * use the action we have.
*/ */
action = NULL; action = NULL;
if (!(status & (IRQ_DISABLED | IRQ_INPROGRESS))) { if (likely(!(status & (IRQ_DISABLED | IRQ_INPROGRESS)))) {
action = desc->action; action = desc->action;
status &= ~IRQ_PENDING; /* we commit to handling */ status &= ~IRQ_PENDING; /* we commit to handling */
status |= IRQ_INPROGRESS; /* we are handling it */ status |= IRQ_INPROGRESS; /* we are handling it */
...@@ -363,7 +359,7 @@ asmlinkage unsigned int do_IRQ(struct pt_regs regs) ...@@ -363,7 +359,7 @@ asmlinkage unsigned int do_IRQ(struct pt_regs regs)
a different instance of this same irq, the other processor a different instance of this same irq, the other processor
will take care of it. will take care of it.
*/ */
if (!action) if (unlikely(!action))
goto out; goto out;
/* /*
...@@ -381,12 +377,12 @@ asmlinkage unsigned int do_IRQ(struct pt_regs regs) ...@@ -381,12 +377,12 @@ asmlinkage unsigned int do_IRQ(struct pt_regs regs)
handle_IRQ_event(irq, &regs, action); handle_IRQ_event(irq, &regs, action);
spin_lock(&desc->lock); spin_lock(&desc->lock);
if (!(desc->status & IRQ_PENDING)) if (likely(!(desc->status & IRQ_PENDING)))
break; break;
desc->status &= ~IRQ_PENDING; desc->status &= ~IRQ_PENDING;
} }
desc->status &= ~IRQ_INPROGRESS;
out: out:
desc->status &= ~IRQ_INPROGRESS;
/* /*
* The ->end() handler has to deal with interrupts which got * The ->end() handler has to deal with interrupts which got
* disabled while the handler was running. * disabled while the handler was running.
......
...@@ -54,7 +54,7 @@ static pmd_t * __init one_md_table_init(pgd_t *pgd) ...@@ -54,7 +54,7 @@ static pmd_t * __init one_md_table_init(pgd_t *pgd)
#if CONFIG_X86_PAE #if CONFIG_X86_PAE
pmd_table = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE); 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)) if (pmd_table != pmd_offset(pgd, 0))
BUG(); BUG();
#else #else
......
...@@ -109,6 +109,7 @@ ...@@ -109,6 +109,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/hdreg.h> #include <linux/hdreg.h>
#include <linux/ide.h> #include <linux/ide.h>
#include <linux/pci.h>
#include <asm/io.h> #include <asm/io.h>
...@@ -163,6 +164,12 @@ int cmd640_vlb = 0; ...@@ -163,6 +164,12 @@ int cmd640_vlb = 0;
#define DRWTIM23 0x58 #define DRWTIM23 0x58
#define BRST 0x59 #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: * Registers and masks for easy access by drive index:
*/ */
...@@ -171,12 +178,6 @@ static u8 prefetch_masks[4] = {CNTRL_DIS_RA0, CNTRL_DIS_RA1, ARTTIM23_DIS_RA2, A ...@@ -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 #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 arttim_regs[4] = {ARTTIM0, ARTTIM1, ARTTIM23, ARTTIM23};
static u8 drwtim_regs[4] = {DRWTIM0, DRWTIM1, DRWTIM23, DRWTIM23}; static u8 drwtim_regs[4] = {DRWTIM0, DRWTIM1, DRWTIM23, DRWTIM23};
...@@ -214,19 +215,16 @@ static unsigned int cmd640_chip_version; ...@@ -214,19 +215,16 @@ static unsigned int cmd640_chip_version;
* Therefore, we must use direct IO instead. * 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 */ /* PCI method 1 access */
static void put_cmd640_reg_pci1 (unsigned short reg, u8 val) static void put_cmd640_reg_pci1 (unsigned short reg, u8 val)
{ {
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&cmd640_lock, flags); spin_lock_irqsave(&pci_lock, flags);
outl_p((reg & 0xfc) | cmd640_key, 0xcf8); outb_p((reg & 0xfc) | cmd640_key, 0xcf8);
outb_p(val, (reg & 3) | 0xcfc); 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) static u8 get_cmd640_reg_pci1 (unsigned short reg)
...@@ -234,10 +232,10 @@ static u8 get_cmd640_reg_pci1 (unsigned short reg) ...@@ -234,10 +232,10 @@ static u8 get_cmd640_reg_pci1 (unsigned short reg)
u8 b; u8 b;
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&cmd640_lock, flags); spin_lock_irqsave(&pci_lock, flags);
outl_p((reg & 0xfc) | cmd640_key, 0xcf8); outb_p((reg & 0xfc) | cmd640_key, 0xcf8);
b = inb_p((reg & 3) | 0xcfc); b=inb_p((reg & 3) | 0xcfc);
spin_unlock_irqrestore(&cmd640_lock, flags); spin_unlock_irqrestore(&pci_lock, flags);
return b; return b;
} }
...@@ -247,11 +245,11 @@ static void put_cmd640_reg_pci2 (unsigned short reg, u8 val) ...@@ -247,11 +245,11 @@ static void put_cmd640_reg_pci2 (unsigned short reg, u8 val)
{ {
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&cmd640_lock, flags); spin_lock_irqsave(&pci_lock, flags);
outb_p(0x10, 0xcf8); outb_p(0x10, 0xcf8);
outb_p(val, cmd640_key + reg); outb_p(val, cmd640_key + reg);
outb_p(0, 0xcf8); 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) static u8 get_cmd640_reg_pci2 (unsigned short reg)
...@@ -259,11 +257,11 @@ static u8 get_cmd640_reg_pci2 (unsigned short reg) ...@@ -259,11 +257,11 @@ static u8 get_cmd640_reg_pci2 (unsigned short reg)
u8 b; u8 b;
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&cmd640_lock, flags); spin_lock_irqsave(&pci_lock, flags);
outb_p(0x10, 0xcf8); outb_p(0x10, 0xcf8);
b = inb_p(cmd640_key + reg); b = inb_p(cmd640_key + reg);
outb_p(0, 0xcf8); outb_p(0, 0xcf8);
spin_unlock_irqrestore(&cmd640_lock, flags); spin_unlock_irqrestore(&pci_lock, flags);
return b; return b;
} }
...@@ -574,7 +572,7 @@ static void program_drive_counts (unsigned int index) ...@@ -574,7 +572,7 @@ static void program_drive_counts (unsigned int index)
/* /*
* Now that everything is ready, program the new timings * 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, * Program the address_setup clocks into ARTTIM reg,
* and then the active/recovery counts into the DRWTIM reg * and then the active/recovery counts into the DRWTIM reg
...@@ -695,9 +693,61 @@ static void cmd640_tune_drive(struct ata_device *drive, u8 mode_wanted) ...@@ -695,9 +693,61 @@ static void cmd640_tune_drive(struct ata_device *drive, u8 mode_wanted)
#endif #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 * Probe for a cmd640 chipset, and initialize it if found. Called from ide.c
*/ */
int __init ide_probe_for_cmd640x(void) int __init ide_probe_for_cmd640x(void)
{ {
#ifdef CONFIG_BLK_DEV_CMD640_ENHANCED #ifdef CONFIG_BLK_DEV_CMD640_ENHANCED
...@@ -712,9 +762,9 @@ int __init ide_probe_for_cmd640x(void) ...@@ -712,9 +762,9 @@ int __init ide_probe_for_cmd640x(void)
bus_type = "VLB"; bus_type = "VLB";
} else { } else {
cmd640_vlb = 0; cmd640_vlb = 0;
if (probe_for_cmd640_pci1()) if (pci_conf1() && probe_for_cmd640_pci1())
bus_type = "PCI (type1)"; bus_type = "PCI (type1)";
else if (probe_for_cmd640_pci2()) else if (pci_conf2() && probe_for_cmd640_pci2())
bus_type = "PCI (type2)"; bus_type = "PCI (type2)";
else else
return 0; return 0;
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* configuration space. * 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 * Wrappers for all PCI configuration access functions. They just check
...@@ -44,3 +44,4 @@ EXPORT_SYMBOL(pci_read_config_dword); ...@@ -44,3 +44,4 @@ EXPORT_SYMBOL(pci_read_config_dword);
EXPORT_SYMBOL(pci_write_config_byte); EXPORT_SYMBOL(pci_write_config_byte);
EXPORT_SYMBOL(pci_write_config_word); EXPORT_SYMBOL(pci_write_config_word);
EXPORT_SYMBOL(pci_write_config_dword); EXPORT_SYMBOL(pci_write_config_dword);
EXPORT_SYMBOL(pci_lock);
...@@ -124,13 +124,13 @@ __asm__( ...@@ -124,13 +124,13 @@ __asm__(
".previous \n" ".previous \n"
); );
#define Q_SET_SEL(selname, address, size) \ #define Q_SET_SEL(cpu, selname, address, size) \
set_base (gdt [(selname) >> 3], __va((u32)(address))); \ set_base(cpu_gdt_table[cpu][(selname) >> 3], __va((u32)(address))); \
set_limit (gdt [(selname) >> 3], size) _set_limit(&cpu_gdt_table[cpu][(selname) >> 3], size)
#define Q2_SET_SEL(selname, address, size) \ #define Q2_SET_SEL(cpu, selname, address, size) \
set_base (gdt [(selname) >> 3], (u32)(address)); \ set_base(cpu_gdt_table[cpu][(selname) >> 3], (u32)(address)); \
set_limit (gdt [(selname) >> 3], size) _set_limit((char *)&cpu_gdt_table[cpu][(selname) >> 3], size)
/* /*
* At some point we want to use this stack frame pointer to unwind * 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, ...@@ -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. */ /* On some boxes IRQ's during PnP BIOS calls are deadly. */
spin_lock_irqsave(&pnp_bios_lock, flags); spin_lock_irqsave(&pnp_bios_lock, flags);
/* The lock prevents us bouncing CPU here */
if (ts1_size) 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) 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__( __asm__ __volatile__(
"pushl %%ebp\n\t" "pushl %%ebp\n\t"
...@@ -1265,12 +1266,16 @@ int __init pnpbios_init(void) ...@@ -1265,12 +1266,16 @@ int __init pnpbios_init(void)
check->fields.version >> 4, check->fields.version & 15, check->fields.version >> 4, check->fields.version & 15,
check->fields.pm16cseg, check->fields.pm16offset, check->fields.pm16cseg, check->fields.pm16offset,
check->fields.pm16dseg); 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.offset = check->fields.pm16offset;
pnp_bios_callpoint.segment = PNP_CS16; pnp_bios_callpoint.segment = PNP_CS16;
pnp_bios_hdr = check; 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; break;
} }
if (!pnp_bios_present()) if (!pnp_bios_present())
......
...@@ -1242,6 +1242,9 @@ int fcntl_setlease(unsigned int fd, struct file *filp, long arg) ...@@ -1242,6 +1242,9 @@ int fcntl_setlease(unsigned int fd, struct file *filp, long arg)
return -EACCES; return -EACCES;
if (!S_ISREG(inode->i_mode)) if (!S_ISREG(inode->i_mode))
return -EINVAL; return -EINVAL;
error = security_ops->file_lock(filp, arg);
if (error)
return error;
lock_kernel(); lock_kernel();
...@@ -1359,8 +1362,7 @@ asmlinkage long sys_flock(unsigned int fd, unsigned int cmd) ...@@ -1359,8 +1362,7 @@ asmlinkage long sys_flock(unsigned int fd, unsigned int cmd)
if (error < 0) if (error < 0)
goto out_putf; goto out_putf;
error = security_ops->file_lock(filp, cmd, error = security_ops->file_lock(filp, lock->fl_type);
(cmd & LOCK_NB) ? 0 : 1);
if (error) if (error)
goto out_putf; goto out_putf;
...@@ -1494,8 +1496,7 @@ int fcntl_setlk(struct file *filp, unsigned int cmd, struct flock *l) ...@@ -1494,8 +1496,7 @@ int fcntl_setlk(struct file *filp, unsigned int cmd, struct flock *l)
goto out; goto out;
} }
error = security_ops->file_lock(filp, file_lock->fl_type, error = security_ops->file_lock(filp, file_lock->fl_type);
cmd == F_SETLKW);
if (error) if (error)
goto out; goto out;
...@@ -1618,8 +1619,7 @@ int fcntl_setlk64(struct file *filp, unsigned int cmd, struct flock64 *l) ...@@ -1618,8 +1619,7 @@ int fcntl_setlk64(struct file *filp, unsigned int cmd, struct flock64 *l)
goto out; goto out;
} }
error = security_ops->file_lock(filp, file_lock->fl_type, error = security_ops->file_lock(filp, file_lock->fl_type);
cmd == F_SETLKW64);
if (error) if (error)
goto out; goto out;
......
...@@ -25,7 +25,7 @@ if [ "$CONFIG_PARTITION_ADVANCED" = "y" ]; then ...@@ -25,7 +25,7 @@ if [ "$CONFIG_PARTITION_ADVANCED" = "y" ]; then
bool ' Solaris (x86) partition table support' CONFIG_SOLARIS_X86_PARTITION bool ' Solaris (x86) partition table support' CONFIG_SOLARIS_X86_PARTITION
bool ' Unixware slices support' CONFIG_UNIXWARE_DISKLABEL bool ' Unixware slices support' CONFIG_UNIXWARE_DISKLABEL
fi 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 if [ "$CONFIG_LDM_PARTITION" = "y" ]; then
bool ' Windows LDM extra logging' CONFIG_LDM_DEBUG bool ' Windows LDM extra logging' CONFIG_LDM_DEBUG
fi fi
......
...@@ -385,87 +385,6 @@ static struct { ...@@ -385,87 +385,6 @@ static struct {
{SOLARIS_X86_PARTITION, parse_solaris_x86}, {SOLARIS_X86_PARTITION, parse_solaris_x86},
{0, NULL}, {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, &sect);
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) 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) ...@@ -474,11 +393,7 @@ int msdos_partition(struct parsed_partitions *state, struct block_device *bdev)
unsigned char *data; unsigned char *data;
struct partition *p; struct partition *p;
int slot; int slot;
int err;
err = handle_ide_mess(bdev);
if (err <= 0)
return err;
data = read_dev_sector(bdev, 0, &sect); data = read_dev_sector(bdev, 0, &sect);
if (!data) if (!data)
return -1; return -1;
...@@ -524,21 +439,6 @@ int msdos_partition(struct parsed_partitions *state, struct block_device *bdev) ...@@ -524,21 +439,6 @@ int msdos_partition(struct parsed_partitions *state, struct block_device *bdev)
state->parts[slot].flags = 1; 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"); printk("\n");
/* second pass - output for each on a separate line */ /* second pass - output for each on a separate line */
...@@ -556,7 +456,7 @@ int msdos_partition(struct parsed_partitions *state, struct block_device *bdev) ...@@ -556,7 +456,7 @@ int msdos_partition(struct parsed_partitions *state, struct block_device *bdev)
if (!subtypes[n].parse) if (!subtypes[n].parse)
continue; continue;
subtypes[n].parse(state, bdev, START_SECT(p)*sector_size, 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); put_dev_sector(sect);
return 1; return 1;
......
...@@ -6,63 +6,4 @@ ...@@ -6,63 +6,4 @@
* Copyright (C) 1998-2001 Russell King * Copyright (C) 1998-2001 Russell King
* (C) 1998 Phil Blundell * (C) 1998 Phil Blundell
*/ */
#include <linux/config.h> #define kbd_init_hw() do { } while (0)
#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)
...@@ -17,13 +17,6 @@ ...@@ -17,13 +17,6 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* *
* Keyboard driver definitions for the Integrator architecture * Keyboard driver definitions for the Integrator architecture
* Now using the input subsystem...
*/ */
#include <asm/irq.h> #define kbd_init_hw() do { } while (0)
#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()
...@@ -8,13 +8,6 @@ ...@@ -8,13 +8,6 @@
* published by the Free Software Foundation. * published by the Free Software Foundation.
* *
* Keyboard driver definitions for RiscPC architecture * Keyboard driver definitions for RiscPC architecture
* Now using the input subsystem...
*/ */
#include <asm/irq.h> #define kbd_init_hw() do { } while (0)
#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()
...@@ -13,8 +13,6 @@ ...@@ -13,8 +13,6 @@
#define __ASM_ARCH_HARDWARE_H #define __ASM_ARCH_HARDWARE_H
#include <linux/config.h> #include <linux/config.h>
#include <asm/mach-types.h>
/* Flushing areas */ /* Flushing areas */
#define FLUSH_BASE_PHYS 0xe0000000 /* SA1100 zero bank */ #define FLUSH_BASE_PHYS 0xe0000000 /* SA1100 zero bank */
......
...@@ -8,21 +8,13 @@ ...@@ -8,21 +8,13 @@
#include <linux/config.h> #include <linux/config.h>
#include <asm/mach-types.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 gc_kbd_init_hw(void);
extern void smartio_kbd_init_hw(void); extern void smartio_kbd_init_hw(void);
extern void cerf_kbd_init_hw(void); extern void cerf_kbd_init_hw(void);
static inline void 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()) if (machine_is_graphicsclient())
gc_kbd_init_hw(); gc_kbd_init_hw();
if (machine_is_adsbitsy()) if (machine_is_adsbitsy())
...@@ -31,11 +23,6 @@ static inline void kbd_init_hw(void) ...@@ -31,11 +23,6 @@ static inline void kbd_init_hw(void)
if (machine_is_cerf()) if (machine_is_cerf())
cerf_kbd_init_hw(); cerf_kbd_init_hw();
#endif #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 */ #endif /* _SA1100_KEYBOARD_H */
...@@ -36,7 +36,7 @@ static inline void atomic_add(int i, volatile atomic_t *v) ...@@ -36,7 +36,7 @@ static inline void atomic_add(int i, volatile atomic_t *v)
{ {
unsigned long flags; unsigned long flags;
local_save_flags_cli(flags); local_irq_save(flags);
v->counter += i; v->counter += i;
local_irq_restore(flags); local_irq_restore(flags);
} }
...@@ -45,7 +45,7 @@ static inline void atomic_sub(int i, volatile atomic_t *v) ...@@ -45,7 +45,7 @@ static inline void atomic_sub(int i, volatile atomic_t *v)
{ {
unsigned long flags; unsigned long flags;
local_save_flags_cli(flags); local_irq_save(flags);
v->counter -= i; v->counter -= i;
local_irq_restore(flags); local_irq_restore(flags);
} }
...@@ -54,7 +54,7 @@ static inline void atomic_inc(volatile atomic_t *v) ...@@ -54,7 +54,7 @@ static inline void atomic_inc(volatile atomic_t *v)
{ {
unsigned long flags; unsigned long flags;
local_save_flags_cli(flags); local_irq_save(flags);
v->counter += 1; v->counter += 1;
local_irq_restore(flags); local_irq_restore(flags);
} }
...@@ -63,7 +63,7 @@ static inline void atomic_dec(volatile atomic_t *v) ...@@ -63,7 +63,7 @@ static inline void atomic_dec(volatile atomic_t *v)
{ {
unsigned long flags; unsigned long flags;
local_save_flags_cli(flags); local_irq_save(flags);
v->counter -= 1; v->counter -= 1;
local_irq_restore(flags); local_irq_restore(flags);
} }
...@@ -73,7 +73,7 @@ static inline int atomic_dec_and_test(volatile atomic_t *v) ...@@ -73,7 +73,7 @@ static inline int atomic_dec_and_test(volatile atomic_t *v)
unsigned long flags; unsigned long flags;
int val; int val;
local_save_flags_cli(flags); local_irq_save(flags);
val = v->counter; val = v->counter;
v->counter = val -= 1; v->counter = val -= 1;
local_irq_restore(flags); local_irq_restore(flags);
...@@ -86,7 +86,7 @@ static inline int atomic_add_negative(int i, volatile atomic_t *v) ...@@ -86,7 +86,7 @@ static inline int atomic_add_negative(int i, volatile atomic_t *v)
unsigned long flags; unsigned long flags;
int val; int val;
local_save_flags_cli(flags); local_irq_save(flags);
val = v->counter; val = v->counter;
v->counter = val += i; v->counter = val += i;
local_irq_restore(flags); local_irq_restore(flags);
...@@ -98,7 +98,7 @@ static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr) ...@@ -98,7 +98,7 @@ static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr)
{ {
unsigned long flags; unsigned long flags;
local_save_flags_cli(flags); local_irq_save(flags);
*addr &= ~mask; *addr &= ~mask;
local_irq_restore(flags); local_irq_restore(flags);
} }
......
...@@ -17,27 +17,70 @@ typedef struct { ...@@ -17,27 +17,70 @@ typedef struct {
#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */ #include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
/* /*
* Are we in an interrupt context? Either doing bottom half * We put the hardirq and softirq counter into the preemption
* or hardware interrupt processing? * 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(); \ #define PREEMPT_BITS 8
(local_irq_count(__cpu) + local_bh_count(__cpu) != 0); }) #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 PREEMPT_OFFSET (1UL << PREEMPT_SHIFT)
#define hardirq_endlock(cpu) do { } while (0) #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 #else
#error SMP not supported #error SMP not supported
#endif /* CONFIG_SMP */ #endif
#endif /* __ASM_HARDIRQ_H */ #endif /* __ASM_HARDIRQ_H */
...@@ -529,120 +529,31 @@ ...@@ -529,120 +529,31 @@
* *
*/ */
#define _KBD( x ) _SA1111( 0x0A00 ) #define SA1111_KBD 0x0a00
#define _MSE( x ) _SA1111( 0x0C00 ) #define SA1111_MSE 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
#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 * PCMCIA Interface
......
...@@ -28,6 +28,13 @@ ...@@ -28,6 +28,13 @@
#include <asm/memory.h> #include <asm/memory.h>
#include <asm/arch/hardware.h> #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 * Generic IO read/write. These perform native-endian accesses. Note
* that some architectures will want to re-define __raw_{read,write}w. * that some architectures will want to re-define __raw_{read,write}w.
......
#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 */
...@@ -43,17 +43,23 @@ extern unsigned long cr_alignment; /* defined in entry-armv.S */ ...@@ -43,17 +43,23 @@ extern unsigned long cr_alignment; /* defined in entry-armv.S */
#endif #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 * Save the current interrupt enable state & disable IRQs
*/ */
#define local_save_flags_cli(x) \ #define local_irq_save(x) \
({ \ ({ \
unsigned long temp; \ unsigned long temp; \
__asm__ __volatile__( \ __asm__ __volatile__( \
"mrs %0, cpsr @ save_flags_cli\n" \ "mrs %0, cpsr @ local_irq_save\n" \
" orr %1, %0, #128\n" \ " orr %1, %0, #128\n" \
" msr cpsr_c, %1" \ " msr cpsr_c, %1" \
: "=r" (x), "=r" (temp) \ : "=r" (x), "=r" (temp) \
...@@ -68,7 +74,7 @@ extern unsigned long cr_alignment; /* defined in entry-armv.S */ ...@@ -68,7 +74,7 @@ extern unsigned long cr_alignment; /* defined in entry-armv.S */
({ \ ({ \
unsigned long temp; \ unsigned long temp; \
__asm__ __volatile__( \ __asm__ __volatile__( \
"mrs %0, cpsr @ sti\n" \ "mrs %0, cpsr @ local_irq_enable\n" \
" bic %0, %0, #128\n" \ " bic %0, %0, #128\n" \
" msr cpsr_c, %0" \ " msr cpsr_c, %0" \
: "=r" (temp) \ : "=r" (temp) \
...@@ -83,7 +89,7 @@ extern unsigned long cr_alignment; /* defined in entry-armv.S */ ...@@ -83,7 +89,7 @@ extern unsigned long cr_alignment; /* defined in entry-armv.S */
({ \ ({ \
unsigned long temp; \ unsigned long temp; \
__asm__ __volatile__( \ __asm__ __volatile__( \
"mrs %0, cpsr @ cli\n" \ "mrs %0, cpsr @ local_irq_disable\n" \
" orr %0, %0, #128\n" \ " orr %0, %0, #128\n" \
" msr cpsr_c, %0" \ " msr cpsr_c, %0" \
: "=r" (temp) \ : "=r" (temp) \
...@@ -121,22 +127,12 @@ extern unsigned long cr_alignment; /* defined in entry-armv.S */ ...@@ -121,22 +127,12 @@ extern unsigned long cr_alignment; /* defined in entry-armv.S */
: "memory"); \ : "memory"); \
}) })
/*
* 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 * restore saved IRQ & FIQ state
*/ */
#define local_irq_restore(x) \ #define local_irq_restore(x) \
__asm__ __volatile__( \ __asm__ __volatile__( \
"msr cpsr_c, %0 @ restore_flags\n" \ "msr cpsr_c, %0 @ local_irq_restore\n" \
: \ : \
: "r" (x) \ : "r" (x) \
: "memory") : "memory")
...@@ -168,14 +164,14 @@ static inline unsigned long __xchg(unsigned long x, volatile void *ptr, int size ...@@ -168,14 +164,14 @@ static inline unsigned long __xchg(unsigned long x, volatile void *ptr, int size
switch (size) { switch (size) {
#ifdef swp_is_buggy #ifdef swp_is_buggy
case 1: case 1:
local_save_flags_cli(flags); local_irq_save(flags);
ret = *(volatile unsigned char *)ptr; ret = *(volatile unsigned char *)ptr;
*(volatile unsigned char *)ptr = x; *(volatile unsigned char *)ptr = x;
local_irq_restore(flags); local_irq_restore(flags);
break; break;
case 4: case 4:
local_save_flags_cli(flags); local_irq_save(flags);
ret = *(volatile unsigned long *)ptr; ret = *(volatile unsigned long *)ptr;
*(volatile unsigned long *)ptr = x; *(volatile unsigned long *)ptr = x;
local_irq_restore(flags); local_irq_restore(flags);
......
#ifndef _ARM_RMAP_H #ifndef _ARM_RMAP_H
#define _ARM_RMAP_H #define _ARM_RMAP_H
#include <asm/proc/rmap.h> #include <asm-generic/rmap.h>
#endif /* _ARM_RMAP_H */ #endif /* _ARM_RMAP_H */
#ifndef __ASM_SOFTIRQ_H #ifndef __ASM_SOFTIRQ_H
#define __ASM_SOFTIRQ_H #define __ASM_SOFTIRQ_H
#include <asm/atomic.h> #include <linux/preempt.h>
#include <asm/hardirq.h> #include <asm/hardirq.h>
#define __cpu_bh_enable(cpu) \ #define local_bh_disable() \
do { barrier(); local_bh_count(cpu)--; preempt_enable(); } while (0) do { preempt_count() += SOFTIRQ_OFFSET; barrier(); } while (0)
#define cpu_bh_disable(cpu) \ #define __local_bh_enable() \
do { preempt_disable(); local_bh_count(cpu)++; barrier(); } while (0) do { barrier(); preempt_count() -= SOFTIRQ_OFFSET; } while (0)
#define local_bh_disable() cpu_bh_disable(smp_processor_id()) #define local_bh_enable() \
#define __local_bh_enable() __cpu_bh_enable(smp_processor_id())
#define in_softirq() (local_bh_count(smp_processor_id()) != 0)
#define _local_bh_enable() \
do { \ do { \
unsigned int *ptr = &local_bh_count(smp_processor_id()); \ __local_bh_enable(); \
if (!--*ptr && ptr[-2]) \ if (unlikely(!in_interrupt() && softirq_pending(smp_processor_id()))) \
__asm__("bl%? __do_softirq": : : "lr");/* out of line */\ __asm__("bl%? __do_softirq": : : "lr");/* out of line */\
preempt_check_resched(); \
} while (0) } while (0)
#define local_bh_enable() do { _local_bh_enable(); preempt_enable(); } while (0)
#endif /* __ASM_SOFTIRQ_H */ #endif /* __ASM_SOFTIRQ_H */
...@@ -64,20 +64,12 @@ extern asmlinkage void __backtrace(void); ...@@ -64,20 +64,12 @@ extern asmlinkage void __backtrace(void);
struct thread_info; struct thread_info;
extern struct task_struct *__switch_to(struct thread_info *, 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) \ #define switch_to(prev,next,last) \
do { \ do { \
__switch_to(prev->thread_info,next->thread_info); \ __switch_to(prev->thread_info,next->thread_info); \
mb(); \ mb(); \
} while (0) } while (0)
/* For spinlocks etc */
#define local_irq_save(x) local_save_flags_cli(x)
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
#error SMP not supported #error SMP not supported
...@@ -91,12 +83,8 @@ extern struct task_struct *__switch_to(struct thread_info *, struct thread_info ...@@ -91,12 +83,8 @@ extern struct task_struct *__switch_to(struct thread_info *, struct thread_info
#define smp_rmb() barrier() #define smp_rmb() barrier()
#define smp_wmb() barrier() #define smp_wmb() barrier()
#define cli() local_irq_disable()
#define sti() local_irq_enable()
#define clf() __clf() #define clf() __clf()
#define stf() __stf() #define stf() __stf()
#define save_flags(x) local_save_flags(x)
#define restore_flags(x) local_irq_restore(x)
#endif /* CONFIG_SMP */ #endif /* CONFIG_SMP */
......
...@@ -567,6 +567,8 @@ int pci_write_config_byte(struct pci_dev *dev, int where, u8 val); ...@@ -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_word(struct pci_dev *dev, int where, u16 val);
int pci_write_config_dword(struct pci_dev *dev, int where, u32 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); int pci_enable_device(struct pci_dev *dev);
void pci_disable_device(struct pci_dev *dev); void pci_disable_device(struct pci_dev *dev);
void pci_set_master(struct pci_dev *dev); void pci_set_master(struct pci_dev *dev);
......
...@@ -407,7 +407,6 @@ struct swap_info_struct; ...@@ -407,7 +407,6 @@ struct swap_info_struct;
* @file contains the file structure. * @file contains the file structure.
* @cmd contains the posix-translated lock operation to perform * @cmd contains the posix-translated lock operation to perform
* (e.g. F_RDLCK, F_WRLCK). * (e.g. F_RDLCK, F_WRLCK).
* @blocking indicates if the request is for a blocking lock.
* Return 0 if permission is granted. * Return 0 if permission is granted.
* @file_fcntl: * @file_fcntl:
* Check permission before allowing the file operation specified by @cmd * Check permission before allowing the file operation specified by @cmd
...@@ -753,7 +752,7 @@ struct security_operations { ...@@ -753,7 +752,7 @@ struct security_operations {
int (*file_mmap) (struct file * file, int (*file_mmap) (struct file * file,
unsigned long prot, unsigned long flags); unsigned long prot, unsigned long flags);
int (*file_mprotect) (struct vm_area_struct * vma, unsigned long prot); 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, int (*file_fcntl) (struct file * file, unsigned int cmd,
unsigned long arg); unsigned long arg);
int (*file_set_fowner) (struct file * file); int (*file_set_fowner) (struct file * file);
......
...@@ -101,9 +101,13 @@ static inline void smp_send_reschedule_all(void) { } ...@@ -101,9 +101,13 @@ static inline void smp_send_reschedule_all(void) { }
#define this_cpu(var) var #define this_cpu(var) var
/* Need to know about CPUs going up/down? */ /* Need to know about CPUs going up/down? */
#define register_cpu_notifier(nb) 0 static inline int register_cpu_notifier(struct notifier_block *nb)
#define unregister_cpu_notifier(nb) do { } while(0) {
return 0;
}
static inline void unregister_cpu_notifier(struct notifier_block *nb)
{
}
#endif /* !SMP */ #endif /* !SMP */
#define get_cpu() ({ preempt_disable(); smp_processor_id(); }) #define get_cpu() ({ preempt_disable(); smp_processor_id(); })
......
...@@ -524,6 +524,19 @@ static void __init do_basic_setup(void) ...@@ -524,6 +524,19 @@ static void __init do_basic_setup(void)
do_initcalls(); 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); extern void prepare_namespace(void);
static int init(void * unused) static int init(void * unused)
...@@ -533,6 +546,9 @@ static int init(void * unused) ...@@ -533,6 +546,9 @@ static int init(void * unused)
lock_kernel(); lock_kernel();
/* Sets up cpus_possible() */ /* Sets up cpus_possible() */
smp_prepare_cpus(max_cpus); smp_prepare_cpus(max_cpus);
do_pre_smp_initcalls();
smp_init(); smp_init();
do_basic_setup(); do_basic_setup();
......
...@@ -16,19 +16,23 @@ ...@@ -16,19 +16,23 @@
* by Davide Libenzi, preemptible kernel bits by Robert Love. * by Davide Libenzi, preemptible kernel bits by Robert Love.
*/ */
#define __KERNEL_SYSCALLS__
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/nmi.h> #include <linux/nmi.h>
#include <linux/init.h> #include <linux/init.h>
#include <asm/uaccess.h> #include <linux/delay.h>
#include <linux/unistd.h>
#include <linux/highmem.h> #include <linux/highmem.h>
#include <linux/security.h>
#include <linux/notifier.h>
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
#include <asm/mmu_context.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/completion.h> #include <linux/completion.h>
#include <linux/kernel_stat.h> #include <linux/kernel_stat.h>
#include <linux/security.h>
#include <linux/notifier.h> #include <asm/uaccess.h>
#include <linux/delay.h> #include <asm/mmu_context.h>
/* /*
* Convert user-nice values [ -20 ... 0 ... 19 ] * Convert user-nice values [ -20 ... 0 ... 19 ]
...@@ -1816,18 +1820,57 @@ void set_cpus_allowed(task_t *p, unsigned long new_mask) ...@@ -1816,18 +1820,57 @@ void set_cpus_allowed(task_t *p, unsigned long new_mask)
preempt_enable(); 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) static int migration_thread(void * bind_cpu)
{ {
int cpu = (int) (long) bind_cpu; int cpu = (int) (long) bind_cpu;
struct sched_param param = { sched_priority: MAX_RT_PRIO-1 }; struct sched_param param = { sched_priority: MAX_RT_PRIO-1 };
migration_startup_t startup;
runqueue_t *rq; runqueue_t *rq;
int ret; int ret, pid;
daemonize(); daemonize();
sigfillset(&current->blocked); sigfillset(&current->blocked);
set_fs(KERNEL_DS); 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()); printk("migration_task %d on cpu=%d\n", cpu, smp_processor_id());
ret = setscheduler(0, SCHED_FIFO, &param); ret = setscheduler(0, SCHED_FIFO, &param);
...@@ -1888,12 +1931,15 @@ static int migration_call(struct notifier_block *nfb, ...@@ -1888,12 +1931,15 @@ static int migration_call(struct notifier_block *nfb,
unsigned long action, unsigned long action,
void *hcpu) void *hcpu)
{ {
unsigned long cpu = (unsigned long)hcpu;
switch (action) { switch (action) {
case CPU_ONLINE: case CPU_ONLINE:
printk("Starting migration thread for cpu %li\n", printk("Starting migration thread for cpu %li\n", cpu);
(long)hcpu); kernel_thread(migration_thread, (void *)cpu,
kernel_thread(migration_thread, hcpu,
CLONE_FS | CLONE_FILES | CLONE_SIGNAL); CLONE_FS | CLONE_FILES | CLONE_SIGNAL);
while (!cpu_rq(cpu)->migration_thread)
yield();
break; break;
} }
return NOTIFY_OK; return NOTIFY_OK;
...@@ -1901,7 +1947,7 @@ static int migration_call(struct notifier_block *nfb, ...@@ -1901,7 +1947,7 @@ static int migration_call(struct notifier_block *nfb,
static struct notifier_block migration_notifier = { &migration_call, NULL, 0 }; 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. */ /* Start one for boot CPU. */
migration_call(&migration_notifier, CPU_ONLINE, migration_call(&migration_notifier, CPU_ONLINE,
...@@ -1910,7 +1956,6 @@ int __init migration_init(void) ...@@ -1910,7 +1956,6 @@ int __init migration_init(void)
return 0; return 0;
} }
__initcall(migration_init);
#endif #endif
extern void init_timervecs(void); extern void init_timervecs(void);
......
...@@ -410,11 +410,9 @@ static int __devinit cpu_callback(struct notifier_block *nfb, ...@@ -410,11 +410,9 @@ static int __devinit cpu_callback(struct notifier_block *nfb,
static struct notifier_block cpu_nfb = { &cpu_callback, NULL, 0 }; 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()); cpu_callback(&cpu_nfb, CPU_ONLINE, (void *)smp_processor_id());
register_cpu_notifier(&cpu_nfb); register_cpu_notifier(&cpu_nfb);
return 0; return 0;
} }
__initcall(spawn_ksoftirqd);
...@@ -2521,7 +2521,7 @@ static int cs_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un ...@@ -2521,7 +2521,7 @@ static int cs_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
{ {
dmabuf = &state->dmabuf; dmabuf = &state->dmabuf;
stop_dac(state); stop_dac(state);
synchronize_irq(); synchronize_irq(card->irq);
dmabuf->ready = 0; dmabuf->ready = 0;
resync_dma_ptrs(state); resync_dma_ptrs(state);
dmabuf->swptr = dmabuf->hwptr = 0; dmabuf->swptr = dmabuf->hwptr = 0;
...@@ -2536,7 +2536,7 @@ static int cs_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un ...@@ -2536,7 +2536,7 @@ static int cs_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
{ {
dmabuf = &state->dmabuf; dmabuf = &state->dmabuf;
stop_adc(state); stop_adc(state);
synchronize_irq(); synchronize_irq(card->irq);
resync_dma_ptrs(state); resync_dma_ptrs(state);
dmabuf->ready = 0; dmabuf->ready = 0;
dmabuf->swptr = dmabuf->hwptr = 0; dmabuf->swptr = dmabuf->hwptr = 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment