diff options
Diffstat (limited to 'arch/frv')
-rw-r--r-- | arch/frv/kernel/Makefile | 2 | ||||
-rw-r--r-- | arch/frv/kernel/entry-table.S | 8 | ||||
-rw-r--r-- | arch/frv/kernel/entry.S | 20 | ||||
-rw-r--r-- | arch/frv/kernel/frv_ksyms.c | 1 | ||||
-rw-r--r-- | arch/frv/kernel/head.inc | 2 | ||||
-rw-r--r-- | arch/frv/kernel/pm.c | 8 | ||||
-rw-r--r-- | arch/frv/kernel/semaphore.c | 155 | ||||
-rw-r--r-- | arch/frv/kernel/switch_to.S | 7 | ||||
-rw-r--r-- | arch/frv/kernel/traps.c | 240 | ||||
-rw-r--r-- | arch/frv/mb93090-mb00/pci-frv.h | 2 | ||||
-rw-r--r-- | arch/frv/mb93090-mb00/pci-vdk.c | 53 | ||||
-rw-r--r-- | arch/frv/mm/highmem.c | 3 |
12 files changed, 263 insertions, 238 deletions
diff --git a/arch/frv/kernel/Makefile b/arch/frv/kernel/Makefile index e8f73ed28b52..c36f70b6699a 100644 --- a/arch/frv/kernel/Makefile +++ b/arch/frv/kernel/Makefile | |||
@@ -9,7 +9,7 @@ extra-y:= head.o init_task.o vmlinux.lds | |||
9 | 9 | ||
10 | obj-y := $(heads-y) entry.o entry-table.o break.o switch_to.o kernel_thread.o \ | 10 | obj-y := $(heads-y) entry.o entry-table.o break.o switch_to.o kernel_thread.o \ |
11 | kernel_execve.o process.o traps.o ptrace.o signal.o dma.o \ | 11 | kernel_execve.o process.o traps.o ptrace.o signal.o dma.o \ |
12 | sys_frv.o time.o semaphore.o setup.o frv_ksyms.o \ | 12 | sys_frv.o time.o setup.o frv_ksyms.o \ |
13 | debug-stub.o irq.o sleep.o uaccess.o | 13 | debug-stub.o irq.o sleep.o uaccess.o |
14 | 14 | ||
15 | obj-$(CONFIG_GDBSTUB) += gdb-stub.o gdb-io.o | 15 | obj-$(CONFIG_GDBSTUB) += gdb-stub.o gdb-io.o |
diff --git a/arch/frv/kernel/entry-table.S b/arch/frv/kernel/entry-table.S index d3b9253d862a..bf35f33e48c9 100644 --- a/arch/frv/kernel/entry-table.S +++ b/arch/frv/kernel/entry-table.S | |||
@@ -316,8 +316,14 @@ __trap_fixup_kernel_data_tlb_miss: | |||
316 | .section .trap.vector | 316 | .section .trap.vector |
317 | .org TBR_TT_TRAP0 >> 2 | 317 | .org TBR_TT_TRAP0 >> 2 |
318 | .long system_call | 318 | .long system_call |
319 | .rept 126 | 319 | .rept 119 |
320 | .long __entry_unsupported_trap | 320 | .long __entry_unsupported_trap |
321 | .endr | 321 | .endr |
322 | |||
323 | # userspace atomic op emulation, traps 120-126 | ||
324 | .rept 7 | ||
325 | .long __entry_atomic_op | ||
326 | .endr | ||
327 | |||
322 | .org TBR_TT_BREAK >> 2 | 328 | .org TBR_TT_BREAK >> 2 |
323 | .long __entry_debug_exception | 329 | .long __entry_debug_exception |
diff --git a/arch/frv/kernel/entry.S b/arch/frv/kernel/entry.S index f36d7f4a7c25..b8a4b94779b1 100644 --- a/arch/frv/kernel/entry.S +++ b/arch/frv/kernel/entry.S | |||
@@ -656,6 +656,26 @@ __entry_debug_exception: | |||
656 | 656 | ||
657 | ############################################################################### | 657 | ############################################################################### |
658 | # | 658 | # |
659 | # handle atomic operation emulation for userspace | ||
660 | # | ||
661 | ############################################################################### | ||
662 | .globl __entry_atomic_op | ||
663 | __entry_atomic_op: | ||
664 | LEDS 0x6012 | ||
665 | sethi.p %hi(atomic_operation),gr5 | ||
666 | setlo %lo(atomic_operation),gr5 | ||
667 | movsg esfr1,gr8 | ||
668 | movsg epcr0,gr9 | ||
669 | movsg esr0,gr10 | ||
670 | |||
671 | # now that we've accessed the exception regs, we can enable exceptions | ||
672 | movsg psr,gr4 | ||
673 | ori gr4,#PSR_ET,gr4 | ||
674 | movgs gr4,psr | ||
675 | jmpl @(gr5,gr0) ; call atomic_operation(esfr1,epcr0,esr0) | ||
676 | |||
677 | ############################################################################### | ||
678 | # | ||
659 | # handle media exception | 679 | # handle media exception |
660 | # | 680 | # |
661 | ############################################################################### | 681 | ############################################################################### |
diff --git a/arch/frv/kernel/frv_ksyms.c b/arch/frv/kernel/frv_ksyms.c index f772704b3d28..0316b3c50eff 100644 --- a/arch/frv/kernel/frv_ksyms.c +++ b/arch/frv/kernel/frv_ksyms.c | |||
@@ -12,7 +12,6 @@ | |||
12 | #include <asm/pgalloc.h> | 12 | #include <asm/pgalloc.h> |
13 | #include <asm/irq.h> | 13 | #include <asm/irq.h> |
14 | #include <asm/io.h> | 14 | #include <asm/io.h> |
15 | #include <asm/semaphore.h> | ||
16 | #include <asm/checksum.h> | 15 | #include <asm/checksum.h> |
17 | #include <asm/hardirq.h> | 16 | #include <asm/hardirq.h> |
18 | #include <asm/cacheflush.h> | 17 | #include <asm/cacheflush.h> |
diff --git a/arch/frv/kernel/head.inc b/arch/frv/kernel/head.inc index d424cd2eb213..bff66628b99a 100644 --- a/arch/frv/kernel/head.inc +++ b/arch/frv/kernel/head.inc | |||
@@ -46,5 +46,5 @@ | |||
46 | #ifdef CONFIG_MMU | 46 | #ifdef CONFIG_MMU |
47 | __sdram_base = 0x00000000 /* base address to which SDRAM relocated */ | 47 | __sdram_base = 0x00000000 /* base address to which SDRAM relocated */ |
48 | #else | 48 | #else |
49 | __sdram_base = 0xc0000000 /* base address to which SDRAM relocated */ | 49 | __sdram_base = __page_offset /* base address to which SDRAM relocated */ |
50 | #endif | 50 | #endif |
diff --git a/arch/frv/kernel/pm.c b/arch/frv/kernel/pm.c index c57ce3f1f2e2..73f3aeefd203 100644 --- a/arch/frv/kernel/pm.c +++ b/arch/frv/kernel/pm.c | |||
@@ -163,14 +163,11 @@ static int sysctl_pm_do_suspend(ctl_table *ctl, int write, struct file *filp, | |||
163 | if ((mode != 1) && (mode != 5)) | 163 | if ((mode != 1) && (mode != 5)) |
164 | return -EINVAL; | 164 | return -EINVAL; |
165 | 165 | ||
166 | retval = pm_send_all(PM_SUSPEND, (void *)3); | ||
167 | |||
168 | if (retval == 0) { | 166 | if (retval == 0) { |
169 | if (mode == 5) | 167 | if (mode == 5) |
170 | retval = pm_do_bus_sleep(); | 168 | retval = pm_do_bus_sleep(); |
171 | else | 169 | else |
172 | retval = pm_do_suspend(); | 170 | retval = pm_do_suspend(); |
173 | pm_send_all(PM_RESUME, (void *)0); | ||
174 | } | 171 | } |
175 | 172 | ||
176 | return retval; | 173 | return retval; |
@@ -183,9 +180,6 @@ static int try_set_cmode(int new_cmode) | |||
183 | if (!(clock_cmodes_permitted & (1<<new_cmode))) | 180 | if (!(clock_cmodes_permitted & (1<<new_cmode))) |
184 | return -EINVAL; | 181 | return -EINVAL; |
185 | 182 | ||
186 | /* tell all the drivers we're suspending */ | ||
187 | pm_send_all(PM_SUSPEND, (void *)3); | ||
188 | |||
189 | /* now change cmode */ | 183 | /* now change cmode */ |
190 | local_irq_disable(); | 184 | local_irq_disable(); |
191 | frv_dma_pause_all(); | 185 | frv_dma_pause_all(); |
@@ -201,8 +195,6 @@ static int try_set_cmode(int new_cmode) | |||
201 | frv_dma_resume_all(); | 195 | frv_dma_resume_all(); |
202 | local_irq_enable(); | 196 | local_irq_enable(); |
203 | 197 | ||
204 | /* tell all the drivers we're resuming */ | ||
205 | pm_send_all(PM_RESUME, (void *)0); | ||
206 | return 0; | 198 | return 0; |
207 | } | 199 | } |
208 | 200 | ||
diff --git a/arch/frv/kernel/semaphore.c b/arch/frv/kernel/semaphore.c deleted file mode 100644 index 7ee3a147b471..000000000000 --- a/arch/frv/kernel/semaphore.c +++ /dev/null | |||
@@ -1,155 +0,0 @@ | |||
1 | /* semaphore.c: FR-V semaphores | ||
2 | * | ||
3 | * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved. | ||
4 | * Written by David Howells (dhowells@redhat.com) | ||
5 | * - Derived from lib/rwsem-spinlock.c | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU General Public License | ||
9 | * as published by the Free Software Foundation; either version | ||
10 | * 2 of the License, or (at your option) any later version. | ||
11 | */ | ||
12 | |||
13 | #include <linux/sched.h> | ||
14 | #include <linux/module.h> | ||
15 | #include <asm/semaphore.h> | ||
16 | |||
17 | struct sem_waiter { | ||
18 | struct list_head list; | ||
19 | struct task_struct *task; | ||
20 | }; | ||
21 | |||
22 | #ifdef CONFIG_DEBUG_SEMAPHORE | ||
23 | void semtrace(struct semaphore *sem, const char *str) | ||
24 | { | ||
25 | if (sem->debug) | ||
26 | printk("[%d] %s({%d,%d})\n", | ||
27 | current->pid, | ||
28 | str, | ||
29 | sem->counter, | ||
30 | list_empty(&sem->wait_list) ? 0 : 1); | ||
31 | } | ||
32 | #else | ||
33 | #define semtrace(SEM,STR) do { } while(0) | ||
34 | #endif | ||
35 | |||
36 | /* | ||
37 | * wait for a token to be granted from a semaphore | ||
38 | * - entered with lock held and interrupts disabled | ||
39 | */ | ||
40 | void __down(struct semaphore *sem, unsigned long flags) | ||
41 | { | ||
42 | struct task_struct *tsk = current; | ||
43 | struct sem_waiter waiter; | ||
44 | |||
45 | semtrace(sem, "Entering __down"); | ||
46 | |||
47 | /* set up my own style of waitqueue */ | ||
48 | waiter.task = tsk; | ||
49 | get_task_struct(tsk); | ||
50 | |||
51 | list_add_tail(&waiter.list, &sem->wait_list); | ||
52 | |||
53 | /* we don't need to touch the semaphore struct anymore */ | ||
54 | spin_unlock_irqrestore(&sem->wait_lock, flags); | ||
55 | |||
56 | /* wait to be given the semaphore */ | ||
57 | set_task_state(tsk, TASK_UNINTERRUPTIBLE); | ||
58 | |||
59 | for (;;) { | ||
60 | if (list_empty(&waiter.list)) | ||
61 | break; | ||
62 | schedule(); | ||
63 | set_task_state(tsk, TASK_UNINTERRUPTIBLE); | ||
64 | } | ||
65 | |||
66 | tsk->state = TASK_RUNNING; | ||
67 | semtrace(sem, "Leaving __down"); | ||
68 | } | ||
69 | |||
70 | EXPORT_SYMBOL(__down); | ||
71 | |||
72 | /* | ||
73 | * interruptibly wait for a token to be granted from a semaphore | ||
74 | * - entered with lock held and interrupts disabled | ||
75 | */ | ||
76 | int __down_interruptible(struct semaphore *sem, unsigned long flags) | ||
77 | { | ||
78 | struct task_struct *tsk = current; | ||
79 | struct sem_waiter waiter; | ||
80 | int ret; | ||
81 | |||
82 | semtrace(sem,"Entering __down_interruptible"); | ||
83 | |||
84 | /* set up my own style of waitqueue */ | ||
85 | waiter.task = tsk; | ||
86 | get_task_struct(tsk); | ||
87 | |||
88 | list_add_tail(&waiter.list, &sem->wait_list); | ||
89 | |||
90 | /* we don't need to touch the semaphore struct anymore */ | ||
91 | set_task_state(tsk, TASK_INTERRUPTIBLE); | ||
92 | |||
93 | spin_unlock_irqrestore(&sem->wait_lock, flags); | ||
94 | |||
95 | /* wait to be given the semaphore */ | ||
96 | ret = 0; | ||
97 | for (;;) { | ||
98 | if (list_empty(&waiter.list)) | ||
99 | break; | ||
100 | if (unlikely(signal_pending(current))) | ||
101 | goto interrupted; | ||
102 | schedule(); | ||
103 | set_task_state(tsk, TASK_INTERRUPTIBLE); | ||
104 | } | ||
105 | |||
106 | out: | ||
107 | tsk->state = TASK_RUNNING; | ||
108 | semtrace(sem, "Leaving __down_interruptible"); | ||
109 | return ret; | ||
110 | |||
111 | interrupted: | ||
112 | spin_lock_irqsave(&sem->wait_lock, flags); | ||
113 | |||
114 | if (!list_empty(&waiter.list)) { | ||
115 | list_del(&waiter.list); | ||
116 | ret = -EINTR; | ||
117 | } | ||
118 | |||
119 | spin_unlock_irqrestore(&sem->wait_lock, flags); | ||
120 | if (ret == -EINTR) | ||
121 | put_task_struct(current); | ||
122 | goto out; | ||
123 | } | ||
124 | |||
125 | EXPORT_SYMBOL(__down_interruptible); | ||
126 | |||
127 | /* | ||
128 | * release a single token back to a semaphore | ||
129 | * - entered with lock held and interrupts disabled | ||
130 | */ | ||
131 | void __up(struct semaphore *sem) | ||
132 | { | ||
133 | struct task_struct *tsk; | ||
134 | struct sem_waiter *waiter; | ||
135 | |||
136 | semtrace(sem,"Entering __up"); | ||
137 | |||
138 | /* grant the token to the process at the front of the queue */ | ||
139 | waiter = list_entry(sem->wait_list.next, struct sem_waiter, list); | ||
140 | |||
141 | /* We must be careful not to touch 'waiter' after we set ->task = NULL. | ||
142 | * It is allocated on the waiter's stack and may become invalid at | ||
143 | * any time after that point (due to a wakeup from another source). | ||
144 | */ | ||
145 | list_del_init(&waiter->list); | ||
146 | tsk = waiter->task; | ||
147 | mb(); | ||
148 | waiter->task = NULL; | ||
149 | wake_up_process(tsk); | ||
150 | put_task_struct(tsk); | ||
151 | |||
152 | semtrace(sem,"Leaving __up"); | ||
153 | } | ||
154 | |||
155 | EXPORT_SYMBOL(__up); | ||
diff --git a/arch/frv/kernel/switch_to.S b/arch/frv/kernel/switch_to.S index b5275fa9cd0d..b06668670fcc 100644 --- a/arch/frv/kernel/switch_to.S +++ b/arch/frv/kernel/switch_to.S | |||
@@ -102,13 +102,6 @@ __switch_to: | |||
102 | movgs gr14,lr | 102 | movgs gr14,lr |
103 | bar | 103 | bar |
104 | 104 | ||
105 | srli gr15,#28,gr5 | ||
106 | subicc gr5,#0xc,gr0,icc0 | ||
107 | beq icc0,#0,111f | ||
108 | break | ||
109 | nop | ||
110 | 111: | ||
111 | |||
112 | # jump to __switch_back or ret_from_fork as appropriate | 105 | # jump to __switch_back or ret_from_fork as appropriate |
113 | # - move prev to GR8 | 106 | # - move prev to GR8 |
114 | movgs gr4,psr | 107 | movgs gr4,psr |
diff --git a/arch/frv/kernel/traps.c b/arch/frv/kernel/traps.c index 2e6098c85578..a40df80b2ebd 100644 --- a/arch/frv/kernel/traps.c +++ b/arch/frv/kernel/traps.c | |||
@@ -49,7 +49,7 @@ asmlinkage void insn_access_error(unsigned long esfr1, unsigned long epcr0, unsi | |||
49 | info.si_signo = SIGSEGV; | 49 | info.si_signo = SIGSEGV; |
50 | info.si_code = SEGV_ACCERR; | 50 | info.si_code = SEGV_ACCERR; |
51 | info.si_errno = 0; | 51 | info.si_errno = 0; |
52 | info.si_addr = (void *) ((epcr0 & EPCR0_V) ? (epcr0 & EPCR0_PC) : __frame->pc); | 52 | info.si_addr = (void __user *) ((epcr0 & EPCR0_V) ? (epcr0 & EPCR0_PC) : __frame->pc); |
53 | 53 | ||
54 | force_sig_info(info.si_signo, &info, current); | 54 | force_sig_info(info.si_signo, &info, current); |
55 | } /* end insn_access_error() */ | 55 | } /* end insn_access_error() */ |
@@ -73,7 +73,7 @@ asmlinkage void illegal_instruction(unsigned long esfr1, unsigned long epcr0, un | |||
73 | epcr0, esr0, esfr1); | 73 | epcr0, esr0, esfr1); |
74 | 74 | ||
75 | info.si_errno = 0; | 75 | info.si_errno = 0; |
76 | info.si_addr = (void *) ((epcr0 & EPCR0_PC) ? (epcr0 & EPCR0_PC) : __frame->pc); | 76 | info.si_addr = (void __user *) ((epcr0 & EPCR0_V) ? (epcr0 & EPCR0_PC) : __frame->pc); |
77 | 77 | ||
78 | switch (__frame->tbr & TBR_TT) { | 78 | switch (__frame->tbr & TBR_TT) { |
79 | case TBR_TT_ILLEGAL_INSTR: | 79 | case TBR_TT_ILLEGAL_INSTR: |
@@ -102,6 +102,234 @@ asmlinkage void illegal_instruction(unsigned long esfr1, unsigned long epcr0, un | |||
102 | 102 | ||
103 | /*****************************************************************************/ | 103 | /*****************************************************************************/ |
104 | /* | 104 | /* |
105 | * handle atomic operations with errors | ||
106 | * - arguments in gr8, gr9, gr10 | ||
107 | * - original memory value placed in gr5 | ||
108 | * - replacement memory value placed in gr9 | ||
109 | */ | ||
110 | asmlinkage void atomic_operation(unsigned long esfr1, unsigned long epcr0, | ||
111 | unsigned long esr0) | ||
112 | { | ||
113 | static DEFINE_SPINLOCK(atomic_op_lock); | ||
114 | unsigned long x, y, z; | ||
115 | unsigned long __user *p; | ||
116 | mm_segment_t oldfs; | ||
117 | siginfo_t info; | ||
118 | int ret; | ||
119 | |||
120 | y = 0; | ||
121 | z = 0; | ||
122 | |||
123 | oldfs = get_fs(); | ||
124 | if (!user_mode(__frame)) | ||
125 | set_fs(KERNEL_DS); | ||
126 | |||
127 | switch (__frame->tbr & TBR_TT) { | ||
128 | /* TIRA gr0,#120 | ||
129 | * u32 __atomic_user_cmpxchg32(u32 *ptr, u32 test, u32 new) | ||
130 | */ | ||
131 | case TBR_TT_ATOMIC_CMPXCHG32: | ||
132 | p = (unsigned long __user *) __frame->gr8; | ||
133 | x = __frame->gr9; | ||
134 | y = __frame->gr10; | ||
135 | |||
136 | for (;;) { | ||
137 | ret = get_user(z, p); | ||
138 | if (ret < 0) | ||
139 | goto error; | ||
140 | |||
141 | if (z != x) | ||
142 | goto done; | ||
143 | |||
144 | spin_lock_irq(&atomic_op_lock); | ||
145 | |||
146 | if (__get_user(z, p) == 0) { | ||
147 | if (z != x) | ||
148 | goto done2; | ||
149 | |||
150 | if (__put_user(y, p) == 0) | ||
151 | goto done2; | ||
152 | goto error2; | ||
153 | } | ||
154 | |||
155 | spin_unlock_irq(&atomic_op_lock); | ||
156 | } | ||
157 | |||
158 | /* TIRA gr0,#121 | ||
159 | * u32 __atomic_kernel_xchg32(void *v, u32 new) | ||
160 | */ | ||
161 | case TBR_TT_ATOMIC_XCHG32: | ||
162 | p = (unsigned long __user *) __frame->gr8; | ||
163 | y = __frame->gr9; | ||
164 | |||
165 | for (;;) { | ||
166 | ret = get_user(z, p); | ||
167 | if (ret < 0) | ||
168 | goto error; | ||
169 | |||
170 | spin_lock_irq(&atomic_op_lock); | ||
171 | |||
172 | if (__get_user(z, p) == 0) { | ||
173 | if (__put_user(y, p) == 0) | ||
174 | goto done2; | ||
175 | goto error2; | ||
176 | } | ||
177 | |||
178 | spin_unlock_irq(&atomic_op_lock); | ||
179 | } | ||
180 | |||
181 | /* TIRA gr0,#122 | ||
182 | * ulong __atomic_kernel_XOR_return(ulong i, ulong *v) | ||
183 | */ | ||
184 | case TBR_TT_ATOMIC_XOR: | ||
185 | p = (unsigned long __user *) __frame->gr8; | ||
186 | x = __frame->gr9; | ||
187 | |||
188 | for (;;) { | ||
189 | ret = get_user(z, p); | ||
190 | if (ret < 0) | ||
191 | goto error; | ||
192 | |||
193 | spin_lock_irq(&atomic_op_lock); | ||
194 | |||
195 | if (__get_user(z, p) == 0) { | ||
196 | y = x ^ z; | ||
197 | if (__put_user(y, p) == 0) | ||
198 | goto done2; | ||
199 | goto error2; | ||
200 | } | ||
201 | |||
202 | spin_unlock_irq(&atomic_op_lock); | ||
203 | } | ||
204 | |||
205 | /* TIRA gr0,#123 | ||
206 | * ulong __atomic_kernel_OR_return(ulong i, ulong *v) | ||
207 | */ | ||
208 | case TBR_TT_ATOMIC_OR: | ||
209 | p = (unsigned long __user *) __frame->gr8; | ||
210 | x = __frame->gr9; | ||
211 | |||
212 | for (;;) { | ||
213 | ret = get_user(z, p); | ||
214 | if (ret < 0) | ||
215 | goto error; | ||
216 | |||
217 | spin_lock_irq(&atomic_op_lock); | ||
218 | |||
219 | if (__get_user(z, p) == 0) { | ||
220 | y = x ^ z; | ||
221 | if (__put_user(y, p) == 0) | ||
222 | goto done2; | ||
223 | goto error2; | ||
224 | } | ||
225 | |||
226 | spin_unlock_irq(&atomic_op_lock); | ||
227 | } | ||
228 | |||
229 | /* TIRA gr0,#124 | ||
230 | * ulong __atomic_kernel_AND_return(ulong i, ulong *v) | ||
231 | */ | ||
232 | case TBR_TT_ATOMIC_AND: | ||
233 | p = (unsigned long __user *) __frame->gr8; | ||
234 | x = __frame->gr9; | ||
235 | |||
236 | for (;;) { | ||
237 | ret = get_user(z, p); | ||
238 | if (ret < 0) | ||
239 | goto error; | ||
240 | |||
241 | spin_lock_irq(&atomic_op_lock); | ||
242 | |||
243 | if (__get_user(z, p) == 0) { | ||
244 | y = x & z; | ||
245 | if (__put_user(y, p) == 0) | ||
246 | goto done2; | ||
247 | goto error2; | ||
248 | } | ||
249 | |||
250 | spin_unlock_irq(&atomic_op_lock); | ||
251 | } | ||
252 | |||
253 | /* TIRA gr0,#125 | ||
254 | * int __atomic_user_sub_return(atomic_t *v, int i) | ||
255 | */ | ||
256 | case TBR_TT_ATOMIC_SUB: | ||
257 | p = (unsigned long __user *) __frame->gr8; | ||
258 | x = __frame->gr9; | ||
259 | |||
260 | for (;;) { | ||
261 | ret = get_user(z, p); | ||
262 | if (ret < 0) | ||
263 | goto error; | ||
264 | |||
265 | spin_lock_irq(&atomic_op_lock); | ||
266 | |||
267 | if (__get_user(z, p) == 0) { | ||
268 | y = z - x; | ||
269 | if (__put_user(y, p) == 0) | ||
270 | goto done2; | ||
271 | goto error2; | ||
272 | } | ||
273 | |||
274 | spin_unlock_irq(&atomic_op_lock); | ||
275 | } | ||
276 | |||
277 | /* TIRA gr0,#126 | ||
278 | * int __atomic_user_add_return(atomic_t *v, int i) | ||
279 | */ | ||
280 | case TBR_TT_ATOMIC_ADD: | ||
281 | p = (unsigned long __user *) __frame->gr8; | ||
282 | x = __frame->gr9; | ||
283 | |||
284 | for (;;) { | ||
285 | ret = get_user(z, p); | ||
286 | if (ret < 0) | ||
287 | goto error; | ||
288 | |||
289 | spin_lock_irq(&atomic_op_lock); | ||
290 | |||
291 | if (__get_user(z, p) == 0) { | ||
292 | y = z + x; | ||
293 | if (__put_user(y, p) == 0) | ||
294 | goto done2; | ||
295 | goto error2; | ||
296 | } | ||
297 | |||
298 | spin_unlock_irq(&atomic_op_lock); | ||
299 | } | ||
300 | |||
301 | default: | ||
302 | BUG(); | ||
303 | } | ||
304 | |||
305 | done2: | ||
306 | spin_unlock_irq(&atomic_op_lock); | ||
307 | done: | ||
308 | if (!user_mode(__frame)) | ||
309 | set_fs(oldfs); | ||
310 | __frame->gr5 = z; | ||
311 | __frame->gr9 = y; | ||
312 | return; | ||
313 | |||
314 | error2: | ||
315 | spin_unlock_irq(&atomic_op_lock); | ||
316 | error: | ||
317 | if (!user_mode(__frame)) | ||
318 | set_fs(oldfs); | ||
319 | __frame->pc -= 4; | ||
320 | |||
321 | die_if_kernel("-- Atomic Op Error --\n"); | ||
322 | |||
323 | info.si_signo = SIGSEGV; | ||
324 | info.si_code = SEGV_ACCERR; | ||
325 | info.si_errno = 0; | ||
326 | info.si_addr = (void __user *) __frame->pc; | ||
327 | |||
328 | force_sig_info(info.si_signo, &info, current); | ||
329 | } | ||
330 | |||
331 | /*****************************************************************************/ | ||
332 | /* | ||
105 | * | 333 | * |
106 | */ | 334 | */ |
107 | asmlinkage void media_exception(unsigned long msr0, unsigned long msr1) | 335 | asmlinkage void media_exception(unsigned long msr0, unsigned long msr1) |
@@ -116,7 +344,7 @@ asmlinkage void media_exception(unsigned long msr0, unsigned long msr1) | |||
116 | info.si_signo = SIGFPE; | 344 | info.si_signo = SIGFPE; |
117 | info.si_code = FPE_MDAOVF; | 345 | info.si_code = FPE_MDAOVF; |
118 | info.si_errno = 0; | 346 | info.si_errno = 0; |
119 | info.si_addr = (void *) __frame->pc; | 347 | info.si_addr = (void __user *) __frame->pc; |
120 | 348 | ||
121 | force_sig_info(info.si_signo, &info, current); | 349 | force_sig_info(info.si_signo, &info, current); |
122 | } /* end media_exception() */ | 350 | } /* end media_exception() */ |
@@ -156,7 +384,7 @@ asmlinkage void memory_access_exception(unsigned long esr0, | |||
156 | info.si_addr = NULL; | 384 | info.si_addr = NULL; |
157 | 385 | ||
158 | if ((esr0 & (ESRx_VALID | ESR0_EAV)) == (ESRx_VALID | ESR0_EAV)) | 386 | if ((esr0 & (ESRx_VALID | ESR0_EAV)) == (ESRx_VALID | ESR0_EAV)) |
159 | info.si_addr = (void *) ear0; | 387 | info.si_addr = (void __user *) ear0; |
160 | 388 | ||
161 | force_sig_info(info.si_signo, &info, current); | 389 | force_sig_info(info.si_signo, &info, current); |
162 | 390 | ||
@@ -185,7 +413,7 @@ asmlinkage void data_access_error(unsigned long esfr1, unsigned long esr15, unsi | |||
185 | info.si_signo = SIGSEGV; | 413 | info.si_signo = SIGSEGV; |
186 | info.si_code = SEGV_ACCERR; | 414 | info.si_code = SEGV_ACCERR; |
187 | info.si_errno = 0; | 415 | info.si_errno = 0; |
188 | info.si_addr = (void *) | 416 | info.si_addr = (void __user *) |
189 | (((esr15 & (ESRx_VALID|ESR15_EAV)) == (ESRx_VALID|ESR15_EAV)) ? ear15 : 0); | 417 | (((esr15 & (ESRx_VALID|ESR15_EAV)) == (ESRx_VALID|ESR15_EAV)) ? ear15 : 0); |
190 | 418 | ||
191 | force_sig_info(info.si_signo, &info, current); | 419 | force_sig_info(info.si_signo, &info, current); |
@@ -219,7 +447,7 @@ asmlinkage void division_exception(unsigned long esfr1, unsigned long esr0, unsi | |||
219 | info.si_signo = SIGFPE; | 447 | info.si_signo = SIGFPE; |
220 | info.si_code = FPE_INTDIV; | 448 | info.si_code = FPE_INTDIV; |
221 | info.si_errno = 0; | 449 | info.si_errno = 0; |
222 | info.si_addr = (void *) __frame->pc; | 450 | info.si_addr = (void __user *) __frame->pc; |
223 | 451 | ||
224 | force_sig_info(info.si_signo, &info, current); | 452 | force_sig_info(info.si_signo, &info, current); |
225 | } /* end division_exception() */ | 453 | } /* end division_exception() */ |
diff --git a/arch/frv/mb93090-mb00/pci-frv.h b/arch/frv/mb93090-mb00/pci-frv.h index 7481797ab382..0c7bf39dc729 100644 --- a/arch/frv/mb93090-mb00/pci-frv.h +++ b/arch/frv/mb93090-mb00/pci-frv.h | |||
@@ -17,8 +17,6 @@ | |||
17 | #define PCI_PROBE_BIOS 0x0001 | 17 | #define PCI_PROBE_BIOS 0x0001 |
18 | #define PCI_PROBE_CONF1 0x0002 | 18 | #define PCI_PROBE_CONF1 0x0002 |
19 | #define PCI_PROBE_CONF2 0x0004 | 19 | #define PCI_PROBE_CONF2 0x0004 |
20 | #define PCI_NO_SORT 0x0100 | ||
21 | #define PCI_BIOS_SORT 0x0200 | ||
22 | #define PCI_NO_CHECKS 0x0400 | 20 | #define PCI_NO_CHECKS 0x0400 |
23 | #define PCI_ASSIGN_ROMS 0x1000 | 21 | #define PCI_ASSIGN_ROMS 0x1000 |
24 | #define PCI_BIOS_IRQ_SCAN 0x2000 | 22 | #define PCI_BIOS_IRQ_SCAN 0x2000 |
diff --git a/arch/frv/mb93090-mb00/pci-vdk.c b/arch/frv/mb93090-mb00/pci-vdk.c index 6d51f133fb23..f003cfa68b7a 100644 --- a/arch/frv/mb93090-mb00/pci-vdk.c +++ b/arch/frv/mb93090-mb00/pci-vdk.c | |||
@@ -199,58 +199,6 @@ static struct pci_ops * __init pci_check_direct(void) | |||
199 | } | 199 | } |
200 | 200 | ||
201 | /* | 201 | /* |
202 | * Several buggy motherboards address only 16 devices and mirror | ||
203 | * them to next 16 IDs. We try to detect this `feature' on all | ||
204 | * primary buses (those containing host bridges as they are | ||
205 | * expected to be unique) and remove the ghost devices. | ||
206 | */ | ||
207 | |||
208 | static void __init pcibios_fixup_ghosts(struct pci_bus *b) | ||
209 | { | ||
210 | struct list_head *ln, *mn; | ||
211 | struct pci_dev *d, *e; | ||
212 | int mirror = PCI_DEVFN(16,0); | ||
213 | int seen_host_bridge = 0; | ||
214 | int i; | ||
215 | |||
216 | for (ln=b->devices.next; ln != &b->devices; ln=ln->next) { | ||
217 | d = pci_dev_b(ln); | ||
218 | if ((d->class >> 8) == PCI_CLASS_BRIDGE_HOST) | ||
219 | seen_host_bridge++; | ||
220 | for (mn=ln->next; mn != &b->devices; mn=mn->next) { | ||
221 | e = pci_dev_b(mn); | ||
222 | if (e->devfn != d->devfn + mirror || | ||
223 | e->vendor != d->vendor || | ||
224 | e->device != d->device || | ||
225 | e->class != d->class) | ||
226 | continue; | ||
227 | for(i=0; i<PCI_NUM_RESOURCES; i++) | ||
228 | if (e->resource[i].start != d->resource[i].start || | ||
229 | e->resource[i].end != d->resource[i].end || | ||
230 | e->resource[i].flags != d->resource[i].flags) | ||
231 | continue; | ||
232 | break; | ||
233 | } | ||
234 | if (mn == &b->devices) | ||
235 | return; | ||
236 | } | ||
237 | if (!seen_host_bridge) | ||
238 | return; | ||
239 | printk("PCI: Ignoring ghost devices on bus %02x\n", b->number); | ||
240 | |||
241 | ln = &b->devices; | ||
242 | while (ln->next != &b->devices) { | ||
243 | d = pci_dev_b(ln->next); | ||
244 | if (d->devfn >= mirror) { | ||
245 | list_del(&d->global_list); | ||
246 | list_del(&d->bus_list); | ||
247 | kfree(d); | ||
248 | } else | ||
249 | ln = ln->next; | ||
250 | } | ||
251 | } | ||
252 | |||
253 | /* | ||
254 | * Discover remaining PCI buses in case there are peer host bridges. | 202 | * Discover remaining PCI buses in case there are peer host bridges. |
255 | * We use the number of last PCI bus provided by the PCI BIOS. | 203 | * We use the number of last PCI bus provided by the PCI BIOS. |
256 | */ | 204 | */ |
@@ -356,7 +304,6 @@ void __init pcibios_fixup_bus(struct pci_bus *bus) | |||
356 | #if 0 | 304 | #if 0 |
357 | printk("### PCIBIOS_FIXUP_BUS(%d)\n",bus->number); | 305 | printk("### PCIBIOS_FIXUP_BUS(%d)\n",bus->number); |
358 | #endif | 306 | #endif |
359 | pcibios_fixup_ghosts(bus); | ||
360 | pci_read_bridge_bases(bus); | 307 | pci_read_bridge_bases(bus); |
361 | 308 | ||
362 | if (bus->number == 0) { | 309 | if (bus->number == 0) { |
diff --git a/arch/frv/mm/highmem.c b/arch/frv/mm/highmem.c index 7f77db7fabc7..eadd07658075 100644 --- a/arch/frv/mm/highmem.c +++ b/arch/frv/mm/highmem.c | |||
@@ -36,6 +36,3 @@ struct page *kmap_atomic_to_page(void *ptr) | |||
36 | { | 36 | { |
37 | return virt_to_page(ptr); | 37 | return virt_to_page(ptr); |
38 | } | 38 | } |
39 | |||
40 | |||
41 | EXPORT_SYMBOL(kmap_atomic_to_page); | ||