aboutsummaryrefslogtreecommitdiffstats
path: root/arch/frv
diff options
context:
space:
mode:
Diffstat (limited to 'arch/frv')
-rw-r--r--arch/frv/Kconfig27
-rw-r--r--arch/frv/Kconfig.debug22
-rw-r--r--arch/frv/Makefile6
-rw-r--r--arch/frv/boot/Makefile4
-rw-r--r--arch/frv/kernel/Makefile2
-rw-r--r--arch/frv/kernel/entry.S2
-rw-r--r--arch/frv/kernel/frv_ksyms.c27
-rw-r--r--arch/frv/kernel/futex.c242
-rw-r--r--arch/frv/kernel/irq.c17
-rw-r--r--arch/frv/kernel/module.c80
-rw-r--r--arch/frv/kernel/pm.c3
-rw-r--r--arch/frv/kernel/process.c26
-rw-r--r--arch/frv/kernel/semaphore.c2
-rw-r--r--arch/frv/kernel/setup.c2
-rw-r--r--arch/frv/kernel/signal.c239
-rw-r--r--arch/frv/kernel/time.c3
-rw-r--r--arch/frv/kernel/traps.c3
-rw-r--r--arch/frv/kernel/uaccess.c7
-rw-r--r--arch/frv/kernel/vmlinux.lds.S1
-rw-r--r--arch/frv/lib/Makefile2
-rw-r--r--arch/frv/lib/__ucmpdi2.S45
-rw-r--r--arch/frv/lib/atomic-ops.S92
-rw-r--r--arch/frv/lib/checksum.c31
-rw-r--r--arch/frv/mb93090-mb00/Makefile2
-rw-r--r--arch/frv/mb93090-mb00/pci-dma-nommu.c8
-rw-r--r--arch/frv/mb93090-mb00/pci-dma.c10
-rw-r--r--arch/frv/mb93090-mb00/pci-frv.c8
-rw-r--r--arch/frv/mb93090-mb00/pci-iomap.c29
-rw-r--r--arch/frv/mb93090-mb00/pci-irq.c6
-rw-r--r--arch/frv/mm/cache-page.c5
-rw-r--r--arch/frv/mm/extable.c34
-rw-r--r--arch/frv/mm/highmem.c8
-rw-r--r--arch/frv/mm/init.c2
-rw-r--r--arch/frv/mm/pgalloc.c6
34 files changed, 653 insertions, 350 deletions
diff --git a/arch/frv/Kconfig b/arch/frv/Kconfig
index ec85c0d6c6..60a617aff8 100644
--- a/arch/frv/Kconfig
+++ b/arch/frv/Kconfig
@@ -6,10 +6,6 @@ config FRV
6 bool 6 bool
7 default y 7 default y
8 8
9config UID16
10 bool
11 default y
12
13config RWSEM_GENERIC_SPINLOCK 9config RWSEM_GENERIC_SPINLOCK
14 bool 10 bool
15 default y 11 default y
@@ -274,6 +270,11 @@ config GPREL_DATA_NONE
274 270
275endchoice 271endchoice
276 272
273config FRV_ONCPU_SERIAL
274 bool "Use on-CPU serial ports"
275 select SERIAL_8250
276 default y
277
277config PCI 278config PCI
278 bool "Use PCI" 279 bool "Use PCI"
279 depends on MB93090_MB00 280 depends on MB93090_MB00
@@ -305,23 +306,7 @@ config RESERVE_DMA_COHERENT
305 306
306source "drivers/pci/Kconfig" 307source "drivers/pci/Kconfig"
307 308
308config PCMCIA 309source "drivers/pcmcia/Kconfig"
309 tristate "Use PCMCIA"
310 help
311 Say Y here if you want to attach PCMCIA- or PC-cards to your FR-V
312 board. These are credit-card size devices such as network cards,
313 modems or hard drives often used with laptops computers. There are
314 actually two varieties of these cards: the older 16 bit PCMCIA cards
315 and the newer 32 bit CardBus cards. If you want to use CardBus
316 cards, you need to say Y here and also to "CardBus support" below.
317
318 To use your PC-cards, you will need supporting software from David
319 Hinds pcmcia-cs package (see the file <file:Documentation/Changes>
320 for location). Please also read the PCMCIA-HOWTO, available from
321 <http://www.tldp.org/docs.html#howto>.
322
323 To compile this driver as modules, choose M here: the
324 modules will be called pcmcia_core and ds.
325 310
326#config MATH_EMULATION 311#config MATH_EMULATION
327# bool "Math emulation support (EXPERIMENTAL)" 312# bool "Math emulation support (EXPERIMENTAL)"
diff --git a/arch/frv/Kconfig.debug b/arch/frv/Kconfig.debug
index 0034b65499..211f01bc4c 100644
--- a/arch/frv/Kconfig.debug
+++ b/arch/frv/Kconfig.debug
@@ -2,32 +2,10 @@ menu "Kernel hacking"
2 2
3source "lib/Kconfig.debug" 3source "lib/Kconfig.debug"
4 4
5config EARLY_PRINTK
6 bool "Early printk"
7 depends on EMBEDDED && DEBUG_KERNEL
8 default n
9 help
10 Write kernel log output directly into the VGA buffer or to a serial
11 port.
12
13 This is useful for kernel debugging when your machine crashes very
14 early before the console code is initialized. For normal operation
15 it is not recommended because it looks ugly and doesn't cooperate
16 with klogd/syslogd or the X server. You should normally N here,
17 unless you want to debug such a crash.
18
19config DEBUG_STACKOVERFLOW 5config DEBUG_STACKOVERFLOW
20 bool "Check for stack overflows" 6 bool "Check for stack overflows"
21 depends on DEBUG_KERNEL 7 depends on DEBUG_KERNEL
22 8
23config DEBUG_PAGEALLOC
24 bool "Page alloc debugging"
25 depends on DEBUG_KERNEL
26 help
27 Unmap pages from the kernel linear mapping after free_pages().
28 This results in a large slowdown, but helps to find certain types
29 of memory corruptions.
30
31config GDBSTUB 9config GDBSTUB
32 bool "Remote GDB kernel debugging" 10 bool "Remote GDB kernel debugging"
33 depends on DEBUG_KERNEL 11 depends on DEBUG_KERNEL
diff --git a/arch/frv/Makefile b/arch/frv/Makefile
index 54046d2386..90c0fb8d9d 100644
--- a/arch/frv/Makefile
+++ b/arch/frv/Makefile
@@ -109,10 +109,10 @@ bootstrap:
109 $(Q)$(MAKEBOOT) bootstrap 109 $(Q)$(MAKEBOOT) bootstrap
110 110
111archmrproper: 111archmrproper:
112 $(Q)$(MAKE) -C arch/frv/boot mrproper 112 $(Q)$(MAKE) $(build)=arch/frv/boot mrproper
113 113
114archclean: 114archclean:
115 $(Q)$(MAKE) -C arch/frv/boot clean 115 $(Q)$(MAKE) $(build)=arch/frv/boot clean
116 116
117archdep: scripts/mkdep symlinks 117archdep: scripts/mkdep symlinks
118 $(Q)$(MAKE) -C arch/frv/boot dep 118 $(Q)$(MAKE) $(build)=arch/frv/boot dep
diff --git a/arch/frv/boot/Makefile b/arch/frv/boot/Makefile
index d75e0d7713..5dfc93fd94 100644
--- a/arch/frv/boot/Makefile
+++ b/arch/frv/boot/Makefile
@@ -57,10 +57,10 @@ initrd:
57# installation 57# installation
58# 58#
59install: $(CONFIGURE) Image 59install: $(CONFIGURE) Image
60 sh ./install.sh $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) Image $(TOPDIR)/System.map "$(INSTALL_PATH)" 60 sh ./install.sh $(KERNELRELEASE) Image $(TOPDIR)/System.map "$(INSTALL_PATH)"
61 61
62zinstall: $(CONFIGURE) zImage 62zinstall: $(CONFIGURE) zImage
63 sh ./install.sh $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) zImage $(TOPDIR)/System.map "$(INSTALL_PATH)" 63 sh ./install.sh $(KERNELRELEASE) zImage $(TOPDIR)/System.map "$(INSTALL_PATH)"
64 64
65# 65#
66# miscellany 66# miscellany
diff --git a/arch/frv/kernel/Makefile b/arch/frv/kernel/Makefile
index 981c2c7dec..5a827b349b 100644
--- a/arch/frv/kernel/Makefile
+++ b/arch/frv/kernel/Makefile
@@ -20,3 +20,5 @@ obj-$(CONFIG_FUJITSU_MB93493) += irq-mb93493.o
20obj-$(CONFIG_PM) += pm.o cmode.o 20obj-$(CONFIG_PM) += pm.o cmode.o
21obj-$(CONFIG_MB93093_PDK) += pm-mb93093.o 21obj-$(CONFIG_MB93093_PDK) += pm-mb93093.o
22obj-$(CONFIG_SYSCTL) += sysctl.o 22obj-$(CONFIG_SYSCTL) += sysctl.o
23obj-$(CONFIG_FUTEX) += futex.o
24obj-$(CONFIG_MODULES) += module.o
diff --git a/arch/frv/kernel/entry.S b/arch/frv/kernel/entry.S
index ad10ea5954..5f6548388b 100644
--- a/arch/frv/kernel/entry.S
+++ b/arch/frv/kernel/entry.S
@@ -1076,7 +1076,7 @@ __entry_work_notifysig:
1076 LEDS 0x6410 1076 LEDS 0x6410
1077 ori.p gr4,#0,gr8 1077 ori.p gr4,#0,gr8
1078 call do_notify_resume 1078 call do_notify_resume
1079 bra __entry_return_direct 1079 bra __entry_resume_userspace
1080 1080
1081 # perform syscall entry tracing 1081 # perform syscall entry tracing
1082__syscall_trace_entry: 1082__syscall_trace_entry:
diff --git a/arch/frv/kernel/frv_ksyms.c b/arch/frv/kernel/frv_ksyms.c
index 1a76d52471..0f1c6cbc4f 100644
--- a/arch/frv/kernel/frv_ksyms.c
+++ b/arch/frv/kernel/frv_ksyms.c
@@ -16,17 +16,16 @@
16#include <asm/semaphore.h> 16#include <asm/semaphore.h>
17#include <asm/checksum.h> 17#include <asm/checksum.h>
18#include <asm/hardirq.h> 18#include <asm/hardirq.h>
19#include <asm/current.h> 19#include <asm/cacheflush.h>
20 20
21extern void dump_thread(struct pt_regs *, struct user *);
22extern long __memcpy_user(void *dst, const void *src, size_t count); 21extern long __memcpy_user(void *dst, const void *src, size_t count);
22extern long __memset_user(void *dst, const void *src, size_t count);
23 23
24/* platform dependent support */ 24/* platform dependent support */
25 25
26EXPORT_SYMBOL(__ioremap); 26EXPORT_SYMBOL(__ioremap);
27EXPORT_SYMBOL(iounmap); 27EXPORT_SYMBOL(iounmap);
28 28
29EXPORT_SYMBOL(dump_thread);
30EXPORT_SYMBOL(strnlen); 29EXPORT_SYMBOL(strnlen);
31EXPORT_SYMBOL(strrchr); 30EXPORT_SYMBOL(strrchr);
32EXPORT_SYMBOL(strstr); 31EXPORT_SYMBOL(strstr);
@@ -50,7 +49,11 @@ EXPORT_SYMBOL(disable_irq);
50EXPORT_SYMBOL(__res_bus_clock_speed_HZ); 49EXPORT_SYMBOL(__res_bus_clock_speed_HZ);
51EXPORT_SYMBOL(__page_offset); 50EXPORT_SYMBOL(__page_offset);
52EXPORT_SYMBOL(__memcpy_user); 51EXPORT_SYMBOL(__memcpy_user);
53EXPORT_SYMBOL(flush_dcache_page); 52EXPORT_SYMBOL(__memset_user);
53EXPORT_SYMBOL(frv_dcache_writeback);
54EXPORT_SYMBOL(frv_cache_invalidate);
55EXPORT_SYMBOL(frv_icache_invalidate);
56EXPORT_SYMBOL(frv_cache_wback_inv);
54 57
55#ifndef CONFIG_MMU 58#ifndef CONFIG_MMU
56EXPORT_SYMBOL(memory_start); 59EXPORT_SYMBOL(memory_start);
@@ -72,6 +75,9 @@ EXPORT_SYMBOL(memcmp);
72EXPORT_SYMBOL(memscan); 75EXPORT_SYMBOL(memscan);
73EXPORT_SYMBOL(memmove); 76EXPORT_SYMBOL(memmove);
74 77
78EXPORT_SYMBOL(__outsl_ns);
79EXPORT_SYMBOL(__insl_ns);
80
75EXPORT_SYMBOL(get_wchan); 81EXPORT_SYMBOL(get_wchan);
76 82
77#ifdef CONFIG_FRV_OUTOFLINE_ATOMIC_OPS 83#ifdef CONFIG_FRV_OUTOFLINE_ATOMIC_OPS
@@ -80,14 +86,13 @@ EXPORT_SYMBOL(atomic_test_and_OR_mask);
80EXPORT_SYMBOL(atomic_test_and_XOR_mask); 86EXPORT_SYMBOL(atomic_test_and_XOR_mask);
81EXPORT_SYMBOL(atomic_add_return); 87EXPORT_SYMBOL(atomic_add_return);
82EXPORT_SYMBOL(atomic_sub_return); 88EXPORT_SYMBOL(atomic_sub_return);
83EXPORT_SYMBOL(__xchg_8);
84EXPORT_SYMBOL(__xchg_16);
85EXPORT_SYMBOL(__xchg_32); 89EXPORT_SYMBOL(__xchg_32);
86EXPORT_SYMBOL(__cmpxchg_8);
87EXPORT_SYMBOL(__cmpxchg_16);
88EXPORT_SYMBOL(__cmpxchg_32); 90EXPORT_SYMBOL(__cmpxchg_32);
89#endif 91#endif
90 92
93EXPORT_SYMBOL(__debug_bug_printk);
94EXPORT_SYMBOL(__delay_loops_MHz);
95
91/* 96/*
92 * libgcc functions - functions that are used internally by the 97 * libgcc functions - functions that are used internally by the
93 * compiler... (prototypes are not correct though, but that 98 * compiler... (prototypes are not correct though, but that
@@ -101,6 +106,8 @@ extern void __divdi3(void);
101extern void __lshrdi3(void); 106extern void __lshrdi3(void);
102extern void __moddi3(void); 107extern void __moddi3(void);
103extern void __muldi3(void); 108extern void __muldi3(void);
109extern void __mulll(void);
110extern void __umulll(void);
104extern void __negdi2(void); 111extern void __negdi2(void);
105extern void __ucmpdi2(void); 112extern void __ucmpdi2(void);
106extern void __udivdi3(void); 113extern void __udivdi3(void);
@@ -116,8 +123,10 @@ EXPORT_SYMBOL(__ashrdi3);
116EXPORT_SYMBOL(__lshrdi3); 123EXPORT_SYMBOL(__lshrdi3);
117//EXPORT_SYMBOL(__moddi3); 124//EXPORT_SYMBOL(__moddi3);
118EXPORT_SYMBOL(__muldi3); 125EXPORT_SYMBOL(__muldi3);
126EXPORT_SYMBOL(__mulll);
127EXPORT_SYMBOL(__umulll);
119EXPORT_SYMBOL(__negdi2); 128EXPORT_SYMBOL(__negdi2);
120//EXPORT_SYMBOL(__ucmpdi2); 129EXPORT_SYMBOL(__ucmpdi2);
121//EXPORT_SYMBOL(__udivdi3); 130//EXPORT_SYMBOL(__udivdi3);
122//EXPORT_SYMBOL(__udivmoddi4); 131//EXPORT_SYMBOL(__udivmoddi4);
123//EXPORT_SYMBOL(__umoddi3); 132//EXPORT_SYMBOL(__umoddi3);
diff --git a/arch/frv/kernel/futex.c b/arch/frv/kernel/futex.c
new file mode 100644
index 0000000000..eae874a970
--- /dev/null
+++ b/arch/frv/kernel/futex.c
@@ -0,0 +1,242 @@
1/* futex.c: futex operations
2 *
3 * Copyright (C) 2005 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11
12#include <linux/futex.h>
13#include <asm/futex.h>
14#include <asm/errno.h>
15#include <asm/uaccess.h>
16
17/*
18 * the various futex operations; MMU fault checking is ignored under no-MMU
19 * conditions
20 */
21static inline int atomic_futex_op_xchg_set(int oparg, int __user *uaddr, int *_oldval)
22{
23 int oldval, ret;
24
25 asm("0: \n"
26 " orcc gr0,gr0,gr0,icc3 \n" /* set ICC3.Z */
27 " ckeq icc3,cc7 \n"
28 "1: ld.p %M0,%1 \n" /* LD.P/ORCR must be atomic */
29 " orcr cc7,cc7,cc3 \n" /* set CC3 to true */
30 "2: cst.p %3,%M0 ,cc3,#1 \n"
31 " corcc gr29,gr29,gr0 ,cc3,#1 \n" /* clear ICC3.Z if store happens */
32 " beq icc3,#0,0b \n"
33 " setlos 0,%2 \n"
34 "3: \n"
35 ".subsection 2 \n"
36 "4: setlos %5,%2 \n"
37 " bra 3b \n"
38 ".previous \n"
39 ".section __ex_table,\"a\" \n"
40 " .balign 8 \n"
41 " .long 1b,4b \n"
42 " .long 2b,4b \n"
43 ".previous"
44 : "+U"(*uaddr), "=&r"(oldval), "=&r"(ret), "=r"(oparg)
45 : "3"(oparg), "i"(-EFAULT)
46 : "memory", "cc7", "cc3", "icc3"
47 );
48
49 *_oldval = oldval;
50 return ret;
51}
52
53static inline int atomic_futex_op_xchg_add(int oparg, int __user *uaddr, int *_oldval)
54{
55 int oldval, ret;
56
57 asm("0: \n"
58 " orcc gr0,gr0,gr0,icc3 \n" /* set ICC3.Z */
59 " ckeq icc3,cc7 \n"
60 "1: ld.p %M0,%1 \n" /* LD.P/ORCR must be atomic */
61 " orcr cc7,cc7,cc3 \n" /* set CC3 to true */
62 " add %1,%3,%3 \n"
63 "2: cst.p %3,%M0 ,cc3,#1 \n"
64 " corcc gr29,gr29,gr0 ,cc3,#1 \n" /* clear ICC3.Z if store happens */
65 " beq icc3,#0,0b \n"
66 " setlos 0,%2 \n"
67 "3: \n"
68 ".subsection 2 \n"
69 "4: setlos %5,%2 \n"
70 " bra 3b \n"
71 ".previous \n"
72 ".section __ex_table,\"a\" \n"
73 " .balign 8 \n"
74 " .long 1b,4b \n"
75 " .long 2b,4b \n"
76 ".previous"
77 : "+U"(*uaddr), "=&r"(oldval), "=&r"(ret), "=r"(oparg)
78 : "3"(oparg), "i"(-EFAULT)
79 : "memory", "cc7", "cc3", "icc3"
80 );
81
82 *_oldval = oldval;
83 return ret;
84}
85
86static inline int atomic_futex_op_xchg_or(int oparg, int __user *uaddr, int *_oldval)
87{
88 int oldval, ret;
89
90 asm("0: \n"
91 " orcc gr0,gr0,gr0,icc3 \n" /* set ICC3.Z */
92 " ckeq icc3,cc7 \n"
93 "1: ld.p %M0,%1 \n" /* LD.P/ORCR must be atomic */
94 " orcr cc7,cc7,cc3 \n" /* set CC3 to true */
95 " or %1,%3,%3 \n"
96 "2: cst.p %3,%M0 ,cc3,#1 \n"
97 " corcc gr29,gr29,gr0 ,cc3,#1 \n" /* clear ICC3.Z if store happens */
98 " beq icc3,#0,0b \n"
99 " setlos 0,%2 \n"
100 "3: \n"
101 ".subsection 2 \n"
102 "4: setlos %5,%2 \n"
103 " bra 3b \n"
104 ".previous \n"
105 ".section __ex_table,\"a\" \n"
106 " .balign 8 \n"
107 " .long 1b,4b \n"
108 " .long 2b,4b \n"
109 ".previous"
110 : "+U"(*uaddr), "=&r"(oldval), "=&r"(ret), "=r"(oparg)
111 : "3"(oparg), "i"(-EFAULT)
112 : "memory", "cc7", "cc3", "icc3"
113 );
114
115 *_oldval = oldval;
116 return ret;
117}
118
119static inline int atomic_futex_op_xchg_and(int oparg, int __user *uaddr, int *_oldval)
120{
121 int oldval, ret;
122
123 asm("0: \n"
124 " orcc gr0,gr0,gr0,icc3 \n" /* set ICC3.Z */
125 " ckeq icc3,cc7 \n"
126 "1: ld.p %M0,%1 \n" /* LD.P/ORCR must be atomic */
127 " orcr cc7,cc7,cc3 \n" /* set CC3 to true */
128 " and %1,%3,%3 \n"
129 "2: cst.p %3,%M0 ,cc3,#1 \n"
130 " corcc gr29,gr29,gr0 ,cc3,#1 \n" /* clear ICC3.Z if store happens */
131 " beq icc3,#0,0b \n"
132 " setlos 0,%2 \n"
133 "3: \n"
134 ".subsection 2 \n"
135 "4: setlos %5,%2 \n"
136 " bra 3b \n"
137 ".previous \n"
138 ".section __ex_table,\"a\" \n"
139 " .balign 8 \n"
140 " .long 1b,4b \n"
141 " .long 2b,4b \n"
142 ".previous"
143 : "+U"(*uaddr), "=&r"(oldval), "=&r"(ret), "=r"(oparg)
144 : "3"(oparg), "i"(-EFAULT)
145 : "memory", "cc7", "cc3", "icc3"
146 );
147
148 *_oldval = oldval;
149 return ret;
150}
151
152static inline int atomic_futex_op_xchg_xor(int oparg, int __user *uaddr, int *_oldval)
153{
154 int oldval, ret;
155
156 asm("0: \n"
157 " orcc gr0,gr0,gr0,icc3 \n" /* set ICC3.Z */
158 " ckeq icc3,cc7 \n"
159 "1: ld.p %M0,%1 \n" /* LD.P/ORCR must be atomic */
160 " orcr cc7,cc7,cc3 \n" /* set CC3 to true */
161 " xor %1,%3,%3 \n"
162 "2: cst.p %3,%M0 ,cc3,#1 \n"
163 " corcc gr29,gr29,gr0 ,cc3,#1 \n" /* clear ICC3.Z if store happens */
164 " beq icc3,#0,0b \n"
165 " setlos 0,%2 \n"
166 "3: \n"
167 ".subsection 2 \n"
168 "4: setlos %5,%2 \n"
169 " bra 3b \n"
170 ".previous \n"
171 ".section __ex_table,\"a\" \n"
172 " .balign 8 \n"
173 " .long 1b,4b \n"
174 " .long 2b,4b \n"
175 ".previous"
176 : "+U"(*uaddr), "=&r"(oldval), "=&r"(ret), "=r"(oparg)
177 : "3"(oparg), "i"(-EFAULT)
178 : "memory", "cc7", "cc3", "icc3"
179 );
180
181 *_oldval = oldval;
182 return ret;
183}
184
185/*****************************************************************************/
186/*
187 * do the futex operations
188 */
189int futex_atomic_op_inuser(int encoded_op, int __user *uaddr)
190{
191 int op = (encoded_op >> 28) & 7;
192 int cmp = (encoded_op >> 24) & 15;
193 int oparg = (encoded_op << 8) >> 20;
194 int cmparg = (encoded_op << 20) >> 20;
195 int oldval = 0, ret;
196
197 if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
198 oparg = 1 << oparg;
199
200 if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
201 return -EFAULT;
202
203 inc_preempt_count();
204
205 switch (op) {
206 case FUTEX_OP_SET:
207 ret = atomic_futex_op_xchg_set(oparg, uaddr, &oldval);
208 break;
209 case FUTEX_OP_ADD:
210 ret = atomic_futex_op_xchg_add(oparg, uaddr, &oldval);
211 break;
212 case FUTEX_OP_OR:
213 ret = atomic_futex_op_xchg_or(oparg, uaddr, &oldval);
214 break;
215 case FUTEX_OP_ANDN:
216 ret = atomic_futex_op_xchg_and(~oparg, uaddr, &oldval);
217 break;
218 case FUTEX_OP_XOR:
219 ret = atomic_futex_op_xchg_xor(oparg, uaddr, &oldval);
220 break;
221 default:
222 ret = -ENOSYS;
223 break;
224 }
225
226 dec_preempt_count();
227
228 if (!ret) {
229 switch (cmp) {
230 case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
231 case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
232 case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
233 case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
234 case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
235 case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
236 default: ret = -ENOSYS; break;
237 }
238 }
239
240 return ret;
241
242} /* end futex_atomic_op_inuser() */
diff --git a/arch/frv/kernel/irq.c b/arch/frv/kernel/irq.c
index 8c524cdd27..59580c59c6 100644
--- a/arch/frv/kernel/irq.c
+++ b/arch/frv/kernel/irq.c
@@ -32,6 +32,7 @@
32#include <linux/irq.h> 32#include <linux/irq.h>
33#include <linux/proc_fs.h> 33#include <linux/proc_fs.h>
34#include <linux/seq_file.h> 34#include <linux/seq_file.h>
35#include <linux/module.h>
35 36
36#include <asm/atomic.h> 37#include <asm/atomic.h>
37#include <asm/io.h> 38#include <asm/io.h>
@@ -178,6 +179,8 @@ void disable_irq_nosync(unsigned int irq)
178 spin_unlock_irqrestore(&level->lock, flags); 179 spin_unlock_irqrestore(&level->lock, flags);
179} 180}
180 181
182EXPORT_SYMBOL(disable_irq_nosync);
183
181/** 184/**
182 * disable_irq - disable an irq and wait for completion 185 * disable_irq - disable an irq and wait for completion
183 * @irq: Interrupt to disable 186 * @irq: Interrupt to disable
@@ -204,6 +207,8 @@ void disable_irq(unsigned int irq)
204#endif 207#endif
205} 208}
206 209
210EXPORT_SYMBOL(disable_irq);
211
207/** 212/**
208 * enable_irq - enable handling of an irq 213 * enable_irq - enable handling of an irq
209 * @irq: Interrupt to enable 214 * @irq: Interrupt to enable
@@ -268,6 +273,8 @@ void enable_irq(unsigned int irq)
268 spin_unlock_irqrestore(&level->lock, flags); 273 spin_unlock_irqrestore(&level->lock, flags);
269} 274}
270 275
276EXPORT_SYMBOL(enable_irq);
277
271/*****************************************************************************/ 278/*****************************************************************************/
272/* 279/*
273 * handles all normal device IRQ's 280 * handles all normal device IRQ's
@@ -425,6 +432,8 @@ int request_irq(unsigned int irq,
425 return retval; 432 return retval;
426} 433}
427 434
435EXPORT_SYMBOL(request_irq);
436
428/** 437/**
429 * free_irq - free an interrupt 438 * free_irq - free an interrupt
430 * @irq: Interrupt line to free 439 * @irq: Interrupt line to free
@@ -496,6 +505,8 @@ void free_irq(unsigned int irq, void *dev_id)
496 } 505 }
497} 506}
498 507
508EXPORT_SYMBOL(free_irq);
509
499/* 510/*
500 * IRQ autodetection code.. 511 * IRQ autodetection code..
501 * 512 *
@@ -519,6 +530,8 @@ unsigned long probe_irq_on(void)
519 return 0; 530 return 0;
520} 531}
521 532
533EXPORT_SYMBOL(probe_irq_on);
534
522/* 535/*
523 * Return a mask of triggered interrupts (this 536 * Return a mask of triggered interrupts (this
524 * can handle only legacy ISA interrupts). 537 * can handle only legacy ISA interrupts).
@@ -542,6 +555,8 @@ unsigned int probe_irq_mask(unsigned long xmask)
542 return 0; 555 return 0;
543} 556}
544 557
558EXPORT_SYMBOL(probe_irq_mask);
559
545/* 560/*
546 * Return the one interrupt that triggered (this can 561 * Return the one interrupt that triggered (this can
547 * handle any interrupt source). 562 * handle any interrupt source).
@@ -571,6 +586,8 @@ int probe_irq_off(unsigned long xmask)
571 return -1; 586 return -1;
572} 587}
573 588
589EXPORT_SYMBOL(probe_irq_off);
590
574/* this was setup_x86_irq but it seems pretty generic */ 591/* this was setup_x86_irq but it seems pretty generic */
575int setup_irq(unsigned int irq, struct irqaction *new) 592int setup_irq(unsigned int irq, struct irqaction *new)
576{ 593{
diff --git a/arch/frv/kernel/module.c b/arch/frv/kernel/module.c
new file mode 100644
index 0000000000..850d168f69
--- /dev/null
+++ b/arch/frv/kernel/module.c
@@ -0,0 +1,80 @@
1/* module.c: FRV specific module loading bits
2 *
3 * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 * - Derived from arch/i386/kernel/module.c, Copyright (C) 2001 Rusty Russell.
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#include <linux/moduleloader.h>
13#include <linux/elf.h>
14#include <linux/vmalloc.h>
15#include <linux/fs.h>
16#include <linux/string.h>
17#include <linux/kernel.h>
18
19#if 0
20#define DEBUGP printk
21#else
22#define DEBUGP(fmt...)
23#endif
24
25void *module_alloc(unsigned long size)
26{
27 if (size == 0)
28 return NULL;
29
30 return vmalloc_exec(size);
31}
32
33
34/* Free memory returned from module_alloc */
35void module_free(struct module *mod, void *module_region)
36{
37 vfree(module_region);
38 /* FIXME: If module_region == mod->init_region, trim exception
39 table entries. */
40}
41
42/* We don't need anything special. */
43int module_frob_arch_sections(Elf_Ehdr *hdr,
44 Elf_Shdr *sechdrs,
45 char *secstrings,
46 struct module *mod)
47{
48 return 0;
49}
50
51int apply_relocate(Elf32_Shdr *sechdrs,
52 const char *strtab,
53 unsigned int symindex,
54 unsigned int relsec,
55 struct module *me)
56{
57 printk(KERN_ERR "module %s: ADD RELOCATION unsupported\n", me->name);
58 return -ENOEXEC;
59}
60
61int apply_relocate_add(Elf32_Shdr *sechdrs,
62 const char *strtab,
63 unsigned int symindex,
64 unsigned int relsec,
65 struct module *me)
66{
67 printk(KERN_ERR "module %s: ADD RELOCATION unsupported\n", me->name);
68 return -ENOEXEC;
69}
70
71int module_finalize(const Elf_Ehdr *hdr,
72 const Elf_Shdr *sechdrs,
73 struct module *me)
74{
75 return 0;
76}
77
78void module_arch_cleanup(struct module *mod)
79{
80}
diff --git a/arch/frv/kernel/pm.c b/arch/frv/kernel/pm.c
index 1a1e8a119c..f0b8fff3e7 100644
--- a/arch/frv/kernel/pm.c
+++ b/arch/frv/kernel/pm.c
@@ -13,7 +13,9 @@
13 13
14#include <linux/config.h> 14#include <linux/config.h>
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/module.h>
16#include <linux/pm.h> 17#include <linux/pm.h>
18#include <linux/pm_legacy.h>
17#include <linux/sched.h> 19#include <linux/sched.h>
18#include <linux/interrupt.h> 20#include <linux/interrupt.h>
19#include <linux/sysctl.h> 21#include <linux/sysctl.h>
@@ -26,6 +28,7 @@
26#include "local.h" 28#include "local.h"
27 29
28void (*pm_power_off)(void); 30void (*pm_power_off)(void);
31EXPORT_SYMBOL(pm_power_off);
29 32
30extern void frv_change_cmode(int); 33extern void frv_change_cmode(int);
31 34
diff --git a/arch/frv/kernel/process.c b/arch/frv/kernel/process.c
index 54a452136f..0fff8a61ef 100644
--- a/arch/frv/kernel/process.c
+++ b/arch/frv/kernel/process.c
@@ -204,7 +204,7 @@ int copy_thread(int nr, unsigned long clone_flags,
204 204
205 regs0 = __kernel_frame0_ptr; 205 regs0 = __kernel_frame0_ptr;
206 childregs0 = (struct pt_regs *) 206 childregs0 = (struct pt_regs *)
207 ((unsigned long) p->thread_info + THREAD_SIZE - USER_CONTEXT_SIZE); 207 (task_stack_page(p) + THREAD_SIZE - USER_CONTEXT_SIZE);
208 childregs = childregs0; 208 childregs = childregs0;
209 209
210 /* set up the userspace frame (the only place that the USP is stored) */ 210 /* set up the userspace frame (the only place that the USP is stored) */
@@ -220,7 +220,7 @@ int copy_thread(int nr, unsigned long clone_flags,
220 *childregs = *regs; 220 *childregs = *regs;
221 childregs->sp = (unsigned long) childregs0; 221 childregs->sp = (unsigned long) childregs0;
222 childregs->next_frame = childregs0; 222 childregs->next_frame = childregs0;
223 childregs->gr15 = (unsigned long) p->thread_info; 223 childregs->gr15 = (unsigned long) task_thread_info(p);
224 childregs->gr29 = (unsigned long) p; 224 childregs->gr29 = (unsigned long) p;
225 } 225 }
226 226
@@ -244,28 +244,6 @@ int copy_thread(int nr, unsigned long clone_flags,
244} /* end copy_thread() */ 244} /* end copy_thread() */
245 245
246/* 246/*
247 * fill in the user structure for a core dump..
248 */
249void dump_thread(struct pt_regs *regs, struct user *dump)
250{
251#if 0
252 /* changed the size calculations - should hopefully work better. lbt */
253 dump->magic = CMAGIC;
254 dump->start_code = 0;
255 dump->start_stack = user_stack(regs) & ~(PAGE_SIZE - 1);
256 dump->u_tsize = ((unsigned long) current->mm->end_code) >> PAGE_SHIFT;
257 dump->u_dsize = ((unsigned long) (current->mm->brk + (PAGE_SIZE-1))) >> PAGE_SHIFT;
258 dump->u_dsize -= dump->u_tsize;
259 dump->u_ssize = 0;
260
261 if (dump->start_stack < TASK_SIZE)
262 dump->u_ssize = ((unsigned long) (TASK_SIZE - dump->start_stack)) >> PAGE_SHIFT;
263
264 dump->regs = *(struct user_context *) regs;
265#endif
266}
267
268/*
269 * sys_execve() executes a new program. 247 * sys_execve() executes a new program.
270 */ 248 */
271asmlinkage int sys_execve(char *name, char **argv, char **envp) 249asmlinkage int sys_execve(char *name, char **argv, char **envp)
diff --git a/arch/frv/kernel/semaphore.c b/arch/frv/kernel/semaphore.c
index 5cba9c1f2b..7971d680ae 100644
--- a/arch/frv/kernel/semaphore.c
+++ b/arch/frv/kernel/semaphore.c
@@ -20,7 +20,7 @@ struct sem_waiter {
20 struct task_struct *task; 20 struct task_struct *task;
21}; 21};
22 22
23#if SEM_DEBUG 23#if SEMAPHORE_DEBUG
24void semtrace(struct semaphore *sem, const char *str) 24void semtrace(struct semaphore *sem, const char *str)
25{ 25{
26 if (sem->debug) 26 if (sem->debug)
diff --git a/arch/frv/kernel/setup.c b/arch/frv/kernel/setup.c
index 767ebb55bd..5908deae96 100644
--- a/arch/frv/kernel/setup.c
+++ b/arch/frv/kernel/setup.c
@@ -787,6 +787,7 @@ void __init setup_arch(char **cmdline_p)
787#endif 787#endif
788 788
789 /* register those serial ports that are available */ 789 /* register those serial ports that are available */
790#ifdef CONFIG_FRV_ONCPU_SERIAL
790#ifndef CONFIG_GDBSTUB_UART0 791#ifndef CONFIG_GDBSTUB_UART0
791 __reg(UART0_BASE + UART_IER * 8) = 0; 792 __reg(UART0_BASE + UART_IER * 8) = 0;
792 early_serial_setup(&__frv_uart0); 793 early_serial_setup(&__frv_uart0);
@@ -795,6 +796,7 @@ void __init setup_arch(char **cmdline_p)
795 __reg(UART1_BASE + UART_IER * 8) = 0; 796 __reg(UART1_BASE + UART_IER * 8) = 0;
796 early_serial_setup(&__frv_uart1); 797 early_serial_setup(&__frv_uart1);
797#endif 798#endif
799#endif
798 800
799#if defined(CONFIG_CHR_DEV_FLASH) || defined(CONFIG_BLK_DEV_FLASH) 801#if defined(CONFIG_CHR_DEV_FLASH) || defined(CONFIG_BLK_DEV_FLASH)
800 /* we need to initialize the Flashrom device here since we might 802 /* we need to initialize the Flashrom device here since we might
diff --git a/arch/frv/kernel/signal.c b/arch/frv/kernel/signal.c
index d4ccc0728d..679c1d5cc9 100644
--- a/arch/frv/kernel/signal.c
+++ b/arch/frv/kernel/signal.c
@@ -35,74 +35,22 @@ struct fdpic_func_descriptor {
35 unsigned long GOT; 35 unsigned long GOT;
36}; 36};
37 37
38asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset);
39
40/* 38/*
41 * Atomically swap in the new signal mask, and wait for a signal. 39 * Atomically swap in the new signal mask, and wait for a signal.
42 */ 40 */
43asmlinkage int sys_sigsuspend(int history0, int history1, old_sigset_t mask) 41asmlinkage int sys_sigsuspend(int history0, int history1, old_sigset_t mask)
44{ 42{
45 sigset_t saveset;
46
47 mask &= _BLOCKABLE; 43 mask &= _BLOCKABLE;
48 spin_lock_irq(&current->sighand->siglock); 44 spin_lock_irq(&current->sighand->siglock);
49 saveset = current->blocked; 45 current->saved_sigmask = current->blocked;
50 siginitset(&current->blocked, mask); 46 siginitset(&current->blocked, mask);
51 recalc_sigpending(); 47 recalc_sigpending();
52 spin_unlock_irq(&current->sighand->siglock); 48 spin_unlock_irq(&current->sighand->siglock);
53 49
54 __frame->gr8 = -EINTR; 50 current->state = TASK_INTERRUPTIBLE;
55 while (1) { 51 schedule();
56 current->state = TASK_INTERRUPTIBLE; 52 set_thread_flag(TIF_RESTORE_SIGMASK);
57 schedule(); 53 return -ERESTARTNOHAND;
58 if (do_signal(__frame, &saveset))
59 /* return the signal number as the return value of this function
60 * - this is an utterly evil hack. syscalls should not invoke do_signal()
61 * as entry.S sets regs->gr8 to the return value of the system call
62 * - we can't just use sigpending() as we'd have to discard SIG_IGN signals
63 * and call waitpid() if SIGCHLD needed discarding
64 * - this only works on the i386 because it passes arguments to the signal
65 * handler on the stack, and the return value in EAX is effectively
66 * discarded
67 */
68 return __frame->gr8;
69 }
70}
71
72asmlinkage int sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize)
73{
74 sigset_t saveset, newset;
75
76 /* XXX: Don't preclude handling different sized sigset_t's. */
77 if (sigsetsize != sizeof(sigset_t))
78 return -EINVAL;
79
80 if (copy_from_user(&newset, unewset, sizeof(newset)))
81 return -EFAULT;
82 sigdelsetmask(&newset, ~_BLOCKABLE);
83
84 spin_lock_irq(&current->sighand->siglock);
85 saveset = current->blocked;
86 current->blocked = newset;
87 recalc_sigpending();
88 spin_unlock_irq(&current->sighand->siglock);
89
90 __frame->gr8 = -EINTR;
91 while (1) {
92 current->state = TASK_INTERRUPTIBLE;
93 schedule();
94 if (do_signal(__frame, &saveset))
95 /* return the signal number as the return value of this function
96 * - this is an utterly evil hack. syscalls should not invoke do_signal()
97 * as entry.S sets regs->gr8 to the return value of the system call
98 * - we can't just use sigpending() as we'd have to discard SIG_IGN signals
99 * and call waitpid() if SIGCHLD needed discarding
100 * - this only works on the i386 because it passes arguments to the signal
101 * handler on the stack, and the return value in EAX is effectively
102 * discarded
103 */
104 return __frame->gr8;
105 }
106} 54}
107 55
108asmlinkage int sys_sigaction(int sig, 56asmlinkage int sys_sigaction(int sig,
@@ -276,13 +224,12 @@ static int setup_sigcontext(struct sigcontext __user *sc, unsigned long mask)
276 * Determine which stack to use.. 224 * Determine which stack to use..
277 */ 225 */
278static inline void __user *get_sigframe(struct k_sigaction *ka, 226static inline void __user *get_sigframe(struct k_sigaction *ka,
279 struct pt_regs *regs,
280 size_t frame_size) 227 size_t frame_size)
281{ 228{
282 unsigned long sp; 229 unsigned long sp;
283 230
284 /* Default to using normal stack */ 231 /* Default to using normal stack */
285 sp = regs->sp; 232 sp = __frame->sp;
286 233
287 /* This is the X/Open sanctioned signal stack switching. */ 234 /* This is the X/Open sanctioned signal stack switching. */
288 if (ka->sa.sa_flags & SA_ONSTACK) { 235 if (ka->sa.sa_flags & SA_ONSTACK) {
@@ -291,18 +238,19 @@ static inline void __user *get_sigframe(struct k_sigaction *ka,
291 } 238 }
292 239
293 return (void __user *) ((sp - frame_size) & ~7UL); 240 return (void __user *) ((sp - frame_size) & ~7UL);
241
294} /* end get_sigframe() */ 242} /* end get_sigframe() */
295 243
296/*****************************************************************************/ 244/*****************************************************************************/
297/* 245/*
298 * 246 *
299 */ 247 */
300static void setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, struct pt_regs * regs) 248static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set)
301{ 249{
302 struct sigframe __user *frame; 250 struct sigframe __user *frame;
303 int rsig; 251 int rsig;
304 252
305 frame = get_sigframe(ka, regs, sizeof(*frame)); 253 frame = get_sigframe(ka, sizeof(*frame));
306 254
307 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 255 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
308 goto give_sigsegv; 256 goto give_sigsegv;
@@ -346,47 +294,51 @@ static void setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, struct p
346 } 294 }
347 295
348 /* set up registers for signal handler */ 296 /* set up registers for signal handler */
349 regs->sp = (unsigned long) frame; 297 __frame->sp = (unsigned long) frame;
350 regs->lr = (unsigned long) &frame->retcode; 298 __frame->lr = (unsigned long) &frame->retcode;
351 regs->gr8 = sig; 299 __frame->gr8 = sig;
352 300
353 if (get_personality & FDPIC_FUNCPTRS) { 301 if (get_personality & FDPIC_FUNCPTRS) {
354 struct fdpic_func_descriptor __user *funcptr = 302 struct fdpic_func_descriptor __user *funcptr =
355 (struct fdpic_func_descriptor *) ka->sa.sa_handler; 303 (struct fdpic_func_descriptor *) ka->sa.sa_handler;
356 __get_user(regs->pc, &funcptr->text); 304 __get_user(__frame->pc, &funcptr->text);
357 __get_user(regs->gr15, &funcptr->GOT); 305 __get_user(__frame->gr15, &funcptr->GOT);
358 } else { 306 } else {
359 regs->pc = (unsigned long) ka->sa.sa_handler; 307 __frame->pc = (unsigned long) ka->sa.sa_handler;
360 regs->gr15 = 0; 308 __frame->gr15 = 0;
361 } 309 }
362 310
363 set_fs(USER_DS); 311 set_fs(USER_DS);
364 312
313 /* the tracer may want to single-step inside the handler */
314 if (test_thread_flag(TIF_SINGLESTEP))
315 ptrace_notify(SIGTRAP);
316
365#if DEBUG_SIG 317#if DEBUG_SIG
366 printk("SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n", 318 printk("SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n",
367 sig, current->comm, current->pid, frame, regs->pc, frame->pretcode); 319 sig, current->comm, current->pid, frame, __frame->pc,
320 frame->pretcode);
368#endif 321#endif
369 322
370 return; 323 return 0;
371 324
372give_sigsegv: 325give_sigsegv:
373 if (sig == SIGSEGV)
374 ka->sa.sa_handler = SIG_DFL;
375
376 force_sig(SIGSEGV, current); 326 force_sig(SIGSEGV, current);
327 return -EFAULT;
328
377} /* end setup_frame() */ 329} /* end setup_frame() */
378 330
379/*****************************************************************************/ 331/*****************************************************************************/
380/* 332/*
381 * 333 *
382 */ 334 */
383static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, 335static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
384 sigset_t *set, struct pt_regs * regs) 336 sigset_t *set)
385{ 337{
386 struct rt_sigframe __user *frame; 338 struct rt_sigframe __user *frame;
387 int rsig; 339 int rsig;
388 340
389 frame = get_sigframe(ka, regs, sizeof(*frame)); 341 frame = get_sigframe(ka, sizeof(*frame));
390 342
391 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 343 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
392 goto give_sigsegv; 344 goto give_sigsegv;
@@ -409,7 +361,7 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
409 if (__put_user(0, &frame->uc.uc_flags) || 361 if (__put_user(0, &frame->uc.uc_flags) ||
410 __put_user(0, &frame->uc.uc_link) || 362 __put_user(0, &frame->uc.uc_link) ||
411 __put_user((void*)current->sas_ss_sp, &frame->uc.uc_stack.ss_sp) || 363 __put_user((void*)current->sas_ss_sp, &frame->uc.uc_stack.ss_sp) ||
412 __put_user(sas_ss_flags(regs->sp), &frame->uc.uc_stack.ss_flags) || 364 __put_user(sas_ss_flags(__frame->sp), &frame->uc.uc_stack.ss_flags) ||
413 __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size)) 365 __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size))
414 goto give_sigsegv; 366 goto give_sigsegv;
415 367
@@ -440,34 +392,38 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
440 } 392 }
441 393
442 /* Set up registers for signal handler */ 394 /* Set up registers for signal handler */
443 regs->sp = (unsigned long) frame; 395 __frame->sp = (unsigned long) frame;
444 regs->lr = (unsigned long) &frame->retcode; 396 __frame->lr = (unsigned long) &frame->retcode;
445 regs->gr8 = sig; 397 __frame->gr8 = sig;
446 regs->gr9 = (unsigned long) &frame->info; 398 __frame->gr9 = (unsigned long) &frame->info;
447 399
448 if (get_personality & FDPIC_FUNCPTRS) { 400 if (get_personality & FDPIC_FUNCPTRS) {
449 struct fdpic_func_descriptor *funcptr = 401 struct fdpic_func_descriptor *funcptr =
450 (struct fdpic_func_descriptor __user *) ka->sa.sa_handler; 402 (struct fdpic_func_descriptor __user *) ka->sa.sa_handler;
451 __get_user(regs->pc, &funcptr->text); 403 __get_user(__frame->pc, &funcptr->text);
452 __get_user(regs->gr15, &funcptr->GOT); 404 __get_user(__frame->gr15, &funcptr->GOT);
453 } else { 405 } else {
454 regs->pc = (unsigned long) ka->sa.sa_handler; 406 __frame->pc = (unsigned long) ka->sa.sa_handler;
455 regs->gr15 = 0; 407 __frame->gr15 = 0;
456 } 408 }
457 409
458 set_fs(USER_DS); 410 set_fs(USER_DS);
459 411
412 /* the tracer may want to single-step inside the handler */
413 if (test_thread_flag(TIF_SINGLESTEP))
414 ptrace_notify(SIGTRAP);
415
460#if DEBUG_SIG 416#if DEBUG_SIG
461 printk("SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n", 417 printk("SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n",
462 sig, current->comm, current->pid, frame, regs->pc, frame->pretcode); 418 sig, current->comm, current->pid, frame, __frame->pc,
419 frame->pretcode);
463#endif 420#endif
464 421
465 return; 422 return 0;
466 423
467give_sigsegv: 424give_sigsegv:
468 if (sig == SIGSEGV)
469 ka->sa.sa_handler = SIG_DFL;
470 force_sig(SIGSEGV, current); 425 force_sig(SIGSEGV, current);
426 return -EFAULT;
471 427
472} /* end setup_rt_frame() */ 428} /* end setup_rt_frame() */
473 429
@@ -475,43 +431,51 @@ give_sigsegv:
475/* 431/*
476 * OK, we're invoking a handler 432 * OK, we're invoking a handler
477 */ 433 */
478static void handle_signal(unsigned long sig, siginfo_t *info, 434static int handle_signal(unsigned long sig, siginfo_t *info,
479 struct k_sigaction *ka, sigset_t *oldset, 435 struct k_sigaction *ka, sigset_t *oldset)
480 struct pt_regs *regs)
481{ 436{
437 int ret;
438
482 /* Are we from a system call? */ 439 /* Are we from a system call? */
483 if (in_syscall(regs)) { 440 if (in_syscall(__frame)) {
484 /* If so, check system call restarting.. */ 441 /* If so, check system call restarting.. */
485 switch (regs->gr8) { 442 switch (__frame->gr8) {
486 case -ERESTART_RESTARTBLOCK: 443 case -ERESTART_RESTARTBLOCK:
487 case -ERESTARTNOHAND: 444 case -ERESTARTNOHAND:
488 regs->gr8 = -EINTR; 445 __frame->gr8 = -EINTR;
489 break; 446 break;
490 447
491 case -ERESTARTSYS: 448 case -ERESTARTSYS:
492 if (!(ka->sa.sa_flags & SA_RESTART)) { 449 if (!(ka->sa.sa_flags & SA_RESTART)) {
493 regs->gr8 = -EINTR; 450 __frame->gr8 = -EINTR;
494 break; 451 break;
495 } 452 }
453
496 /* fallthrough */ 454 /* fallthrough */
497 case -ERESTARTNOINTR: 455 case -ERESTARTNOINTR:
498 regs->gr8 = regs->orig_gr8; 456 __frame->gr8 = __frame->orig_gr8;
499 regs->pc -= 4; 457 __frame->pc -= 4;
500 } 458 }
501 } 459 }
502 460
503 /* Set up the stack frame */ 461 /* Set up the stack frame */
504 if (ka->sa.sa_flags & SA_SIGINFO) 462 if (ka->sa.sa_flags & SA_SIGINFO)
505 setup_rt_frame(sig, ka, info, oldset, regs); 463 ret = setup_rt_frame(sig, ka, info, oldset);
506 else 464 else
507 setup_frame(sig, ka, oldset, regs); 465 ret = setup_frame(sig, ka, oldset);
466
467 if (ret == 0) {
468 spin_lock_irq(&current->sighand->siglock);
469 sigorsets(&current->blocked, &current->blocked,
470 &ka->sa.sa_mask);
471 if (!(ka->sa.sa_flags & SA_NODEFER))
472 sigaddset(&current->blocked, sig);
473 recalc_sigpending();
474 spin_unlock_irq(&current->sighand->siglock);
475 }
476
477 return ret;
508 478
509 spin_lock_irq(&current->sighand->siglock);
510 sigorsets(&current->blocked, &current->blocked, &ka->sa.sa_mask);
511 if (!(ka->sa.sa_flags & SA_NODEFER))
512 sigaddset(&current->blocked, sig);
513 recalc_sigpending();
514 spin_unlock_irq(&current->sighand->siglock);
515} /* end handle_signal() */ 479} /* end handle_signal() */
516 480
517/*****************************************************************************/ 481/*****************************************************************************/
@@ -520,10 +484,11 @@ static void handle_signal(unsigned long sig, siginfo_t *info,
520 * want to handle. Thus you cannot kill init even with a SIGKILL even by 484 * want to handle. Thus you cannot kill init even with a SIGKILL even by
521 * mistake. 485 * mistake.
522 */ 486 */
523int do_signal(struct pt_regs *regs, sigset_t *oldset) 487static void do_signal(void)
524{ 488{
525 struct k_sigaction ka; 489 struct k_sigaction ka;
526 siginfo_t info; 490 siginfo_t info;
491 sigset_t *oldset;
527 int signr; 492 int signr;
528 493
529 /* 494 /*
@@ -532,45 +497,63 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
532 * kernel mode. Just return without doing anything 497 * kernel mode. Just return without doing anything
533 * if so. 498 * if so.
534 */ 499 */
535 if (!user_mode(regs)) 500 if (!user_mode(__frame))
536 return 1; 501 return;
537 502
538 if (try_to_freeze()) 503 if (try_to_freeze())
539 goto no_signal; 504 goto no_signal;
540 505
541 if (!oldset) 506 if (test_thread_flag(TIF_RESTORE_SIGMASK))
507 oldset = &current->saved_sigmask;
508 else
542 oldset = &current->blocked; 509 oldset = &current->blocked;
543 510
544 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 511 signr = get_signal_to_deliver(&info, &ka, __frame, NULL);
545 if (signr > 0) { 512 if (signr > 0) {
546 handle_signal(signr, &info, &ka, oldset, regs); 513 if (handle_signal(signr, &info, &ka, oldset) == 0) {
547 return 1; 514 /* a signal was successfully delivered; the saved
515 * sigmask will have been stored in the signal frame,
516 * and will be restored by sigreturn, so we can simply
517 * clear the TIF_RESTORE_SIGMASK flag */
518 if (test_thread_flag(TIF_RESTORE_SIGMASK))
519 clear_thread_flag(TIF_RESTORE_SIGMASK);
520 }
521
522 return;
548 } 523 }
549 524
550 no_signal: 525no_signal:
551 /* Did we come from a system call? */ 526 /* Did we come from a system call? */
552 if (regs->syscallno >= 0) { 527 if (__frame->syscallno >= 0) {
553 /* Restart the system call - no handlers present */ 528 /* Restart the system call - no handlers present */
554 if (regs->gr8 == -ERESTARTNOHAND || 529 switch (__frame->gr8) {
555 regs->gr8 == -ERESTARTSYS || 530 case -ERESTARTNOHAND:
556 regs->gr8 == -ERESTARTNOINTR) { 531 case -ERESTARTSYS:
557 regs->gr8 = regs->orig_gr8; 532 case -ERESTARTNOINTR:
558 regs->pc -= 4; 533 __frame->gr8 = __frame->orig_gr8;
559 } 534 __frame->pc -= 4;
535 break;
560 536
561 if (regs->gr8 == -ERESTART_RESTARTBLOCK){ 537 case -ERESTART_RESTARTBLOCK:
562 regs->gr8 = __NR_restart_syscall; 538 __frame->gr8 = __NR_restart_syscall;
563 regs->pc -= 4; 539 __frame->pc -= 4;
540 break;
564 } 541 }
565 } 542 }
566 543
567 return 0; 544 /* if there's no signal to deliver, we just put the saved sigmask
545 * back */
546 if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
547 clear_thread_flag(TIF_RESTORE_SIGMASK);
548 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
549 }
550
568} /* end do_signal() */ 551} /* end do_signal() */
569 552
570/*****************************************************************************/ 553/*****************************************************************************/
571/* 554/*
572 * notification of userspace execution resumption 555 * notification of userspace execution resumption
573 * - triggered by current->work.notify_resume 556 * - triggered by the TIF_WORK_MASK flags
574 */ 557 */
575asmlinkage void do_notify_resume(__u32 thread_info_flags) 558asmlinkage void do_notify_resume(__u32 thread_info_flags)
576{ 559{
@@ -579,7 +562,7 @@ asmlinkage void do_notify_resume(__u32 thread_info_flags)
579 clear_thread_flag(TIF_SINGLESTEP); 562 clear_thread_flag(TIF_SINGLESTEP);
580 563
581 /* deal with pending signal delivery */ 564 /* deal with pending signal delivery */
582 if (thread_info_flags & _TIF_SIGPENDING) 565 if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK))
583 do_signal(__frame, NULL); 566 do_signal();
584 567
585} /* end do_notify_resume() */ 568} /* end do_notify_resume() */
diff --git a/arch/frv/kernel/time.c b/arch/frv/kernel/time.c
index 2e9741227b..24cf85f89e 100644
--- a/arch/frv/kernel/time.c
+++ b/arch/frv/kernel/time.c
@@ -189,6 +189,8 @@ void do_gettimeofday(struct timeval *tv)
189 tv->tv_usec = usec; 189 tv->tv_usec = usec;
190} 190}
191 191
192EXPORT_SYMBOL(do_gettimeofday);
193
192int do_settimeofday(struct timespec *tv) 194int do_settimeofday(struct timespec *tv)
193{ 195{
194 time_t wtm_sec, sec = tv->tv_sec; 196 time_t wtm_sec, sec = tv->tv_sec;
@@ -218,6 +220,7 @@ int do_settimeofday(struct timespec *tv)
218 clock_was_set(); 220 clock_was_set();
219 return 0; 221 return 0;
220} 222}
223
221EXPORT_SYMBOL(do_settimeofday); 224EXPORT_SYMBOL(do_settimeofday);
222 225
223/* 226/*
diff --git a/arch/frv/kernel/traps.c b/arch/frv/kernel/traps.c
index 89073cae4b..9eb84b2e6a 100644
--- a/arch/frv/kernel/traps.c
+++ b/arch/frv/kernel/traps.c
@@ -19,6 +19,7 @@
19#include <linux/string.h> 19#include <linux/string.h>
20#include <linux/linkage.h> 20#include <linux/linkage.h>
21#include <linux/init.h> 21#include <linux/init.h>
22#include <linux/module.h>
22 23
23#include <asm/setup.h> 24#include <asm/setup.h>
24#include <asm/fpu.h> 25#include <asm/fpu.h>
@@ -250,6 +251,8 @@ void dump_stack(void)
250 show_stack(NULL, NULL); 251 show_stack(NULL, NULL);
251} 252}
252 253
254EXPORT_SYMBOL(dump_stack);
255
253void show_stack(struct task_struct *task, unsigned long *sp) 256void show_stack(struct task_struct *task, unsigned long *sp)
254{ 257{
255} 258}
diff --git a/arch/frv/kernel/uaccess.c b/arch/frv/kernel/uaccess.c
index f3fd58a5bc..9b751c0f0e 100644
--- a/arch/frv/kernel/uaccess.c
+++ b/arch/frv/kernel/uaccess.c
@@ -10,6 +10,7 @@
10 */ 10 */
11 11
12#include <linux/mm.h> 12#include <linux/mm.h>
13#include <linux/module.h>
13#include <asm/uaccess.h> 14#include <asm/uaccess.h>
14 15
15/*****************************************************************************/ 16/*****************************************************************************/
@@ -58,8 +59,11 @@ long strncpy_from_user(char *dst, const char *src, long count)
58 memset(p, 0, count); /* clear remainder of buffer [security] */ 59 memset(p, 0, count); /* clear remainder of buffer [security] */
59 60
60 return err; 61 return err;
62
61} /* end strncpy_from_user() */ 63} /* end strncpy_from_user() */
62 64
65EXPORT_SYMBOL(strncpy_from_user);
66
63/*****************************************************************************/ 67/*****************************************************************************/
64/* 68/*
65 * Return the size of a string (including the ending 0) 69 * Return the size of a string (including the ending 0)
@@ -92,4 +96,7 @@ long strnlen_user(const char *src, long count)
92 } 96 }
93 97
94 return p - src + 1; /* return length including NUL */ 98 return p - src + 1; /* return length including NUL */
99
95} /* end strnlen_user() */ 100} /* end strnlen_user() */
101
102EXPORT_SYMBOL(strnlen_user);
diff --git a/arch/frv/kernel/vmlinux.lds.S b/arch/frv/kernel/vmlinux.lds.S
index fceafd2cc2..f474534ba7 100644
--- a/arch/frv/kernel/vmlinux.lds.S
+++ b/arch/frv/kernel/vmlinux.lds.S
@@ -112,6 +112,7 @@ SECTIONS
112#endif 112#endif
113 ) 113 )
114 SCHED_TEXT 114 SCHED_TEXT
115 LOCK_TEXT
115 *(.fixup) 116 *(.fixup)
116 *(.gnu.warning) 117 *(.gnu.warning)
117 *(.exitcall.exit) 118 *(.exitcall.exit)
diff --git a/arch/frv/lib/Makefile b/arch/frv/lib/Makefile
index 19be2626d5..08be305c9f 100644
--- a/arch/frv/lib/Makefile
+++ b/arch/frv/lib/Makefile
@@ -3,6 +3,6 @@
3# 3#
4 4
5lib-y := \ 5lib-y := \
6 __ashldi3.o __lshrdi3.o __muldi3.o __ashrdi3.o __negdi2.o \ 6 __ashldi3.o __lshrdi3.o __muldi3.o __ashrdi3.o __negdi2.o __ucmpdi2.o \
7 checksum.o memcpy.o memset.o atomic-ops.o \ 7 checksum.o memcpy.o memset.o atomic-ops.o \
8 outsl_ns.o outsl_sw.o insl_ns.o insl_sw.o cache.o 8 outsl_ns.o outsl_sw.o insl_ns.o insl_sw.o cache.o
diff --git a/arch/frv/lib/__ucmpdi2.S b/arch/frv/lib/__ucmpdi2.S
new file mode 100644
index 0000000000..d892f16ffa
--- /dev/null
+++ b/arch/frv/lib/__ucmpdi2.S
@@ -0,0 +1,45 @@
1/* __ucmpdi2.S: 64-bit unsigned compare
2 *
3 * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11
12
13 .text
14 .p2align 4
15
16###############################################################################
17#
18# int __ucmpdi2(unsigned long long a [GR8:GR9],
19# unsigned long long b [GR10:GR11])
20#
21# - returns 0, 1, or 2 as a <, =, > b respectively.
22#
23###############################################################################
24 .globl __ucmpdi2
25 .type __ucmpdi2,@function
26__ucmpdi2:
27 or.p gr8,gr0,gr4
28 subcc gr8,gr10,gr0,icc0
29 setlos.p #0,gr8
30 bclr icc0,#2 ; a.msw < b.msw
31
32 setlos.p #2,gr8
33 bhilr icc0,#0 ; a.msw > b.msw
34
35 subcc.p gr9,gr11,gr0,icc1
36 setlos #0,gr8
37 setlos.p #2,gr9
38 setlos #1,gr7
39 cknc icc1,cc6
40 cor.p gr9,gr0,gr8, cc6,#1
41 cckls icc1,cc4, cc6,#1
42 andcr cc6,cc4,cc4
43 cor gr7,gr0,gr8, cc4,#1
44 bralr
45 .size __ucmpdi2, .-__ucmpdi2
diff --git a/arch/frv/lib/atomic-ops.S b/arch/frv/lib/atomic-ops.S
index b03d510a89..545cd325ac 100644
--- a/arch/frv/lib/atomic-ops.S
+++ b/arch/frv/lib/atomic-ops.S
@@ -129,48 +129,6 @@ atomic_sub_return:
129 129
130############################################################################### 130###############################################################################
131# 131#
132# uint8_t __xchg_8(uint8_t i, uint8_t *v)
133#
134###############################################################################
135 .globl __xchg_8
136 .type __xchg_8,@function
137__xchg_8:
138 or.p gr8,gr8,gr10
1390:
140 orcc gr0,gr0,gr0,icc3 /* set ICC3.Z */
141 ckeq icc3,cc7
142 ldub.p @(gr9,gr0),gr8 /* LD.P/ORCR must be atomic */
143 orcr cc7,cc7,cc3 /* set CC3 to true */
144 cstb.p gr10,@(gr9,gr0) ,cc3,#1
145 corcc gr29,gr29,gr0 ,cc3,#1 /* clear ICC3.Z if store happens */
146 beq icc3,#0,0b
147 bralr
148
149 .size __xchg_8, .-__xchg_8
150
151###############################################################################
152#
153# uint16_t __xchg_16(uint16_t i, uint16_t *v)
154#
155###############################################################################
156 .globl __xchg_16
157 .type __xchg_16,@function
158__xchg_16:
159 or.p gr8,gr8,gr10
1600:
161 orcc gr0,gr0,gr0,icc3 /* set ICC3.Z */
162 ckeq icc3,cc7
163 lduh.p @(gr9,gr0),gr8 /* LD.P/ORCR must be atomic */
164 orcr cc7,cc7,cc3 /* set CC3 to true */
165 csth.p gr10,@(gr9,gr0) ,cc3,#1
166 corcc gr29,gr29,gr0 ,cc3,#1 /* clear ICC3.Z if store happens */
167 beq icc3,#0,0b
168 bralr
169
170 .size __xchg_16, .-__xchg_16
171
172###############################################################################
173#
174# uint32_t __xchg_32(uint32_t i, uint32_t *v) 132# uint32_t __xchg_32(uint32_t i, uint32_t *v)
175# 133#
176############################################################################### 134###############################################################################
@@ -192,56 +150,6 @@ __xchg_32:
192 150
193############################################################################### 151###############################################################################
194# 152#
195# uint8_t __cmpxchg_8(uint8_t *v, uint8_t test, uint8_t new)
196#
197###############################################################################
198 .globl __cmpxchg_8
199 .type __cmpxchg_8,@function
200__cmpxchg_8:
201 or.p gr8,gr8,gr11
2020:
203 orcc gr0,gr0,gr0,icc3
204 ckeq icc3,cc7
205 ldub.p @(gr11,gr0),gr8
206 orcr cc7,cc7,cc3
207 sub gr8,gr9,gr7
208 sllicc gr7,#24,gr0,icc0
209 bne icc0,#0,1f
210 cstb.p gr10,@(gr11,gr0) ,cc3,#1
211 corcc gr29,gr29,gr0 ,cc3,#1
212 beq icc3,#0,0b
2131:
214 bralr
215
216 .size __cmpxchg_8, .-__cmpxchg_8
217
218###############################################################################
219#
220# uint16_t __cmpxchg_16(uint16_t *v, uint16_t test, uint16_t new)
221#
222###############################################################################
223 .globl __cmpxchg_16
224 .type __cmpxchg_16,@function
225__cmpxchg_16:
226 or.p gr8,gr8,gr11
2270:
228 orcc gr0,gr0,gr0,icc3
229 ckeq icc3,cc7
230 lduh.p @(gr11,gr0),gr8
231 orcr cc7,cc7,cc3
232 sub gr8,gr9,gr7
233 sllicc gr7,#16,gr0,icc0
234 bne icc0,#0,1f
235 csth.p gr10,@(gr11,gr0) ,cc3,#1
236 corcc gr29,gr29,gr0 ,cc3,#1
237 beq icc3,#0,0b
2381:
239 bralr
240
241 .size __cmpxchg_16, .-__cmpxchg_16
242
243###############################################################################
244#
245# uint32_t __cmpxchg_32(uint32_t *v, uint32_t test, uint32_t new) 153# uint32_t __cmpxchg_32(uint32_t *v, uint32_t test, uint32_t new)
246# 154#
247############################################################################### 155###############################################################################
diff --git a/arch/frv/lib/checksum.c b/arch/frv/lib/checksum.c
index 7bf5bd6cac..20e7dfc474 100644
--- a/arch/frv/lib/checksum.c
+++ b/arch/frv/lib/checksum.c
@@ -33,6 +33,7 @@
33 33
34#include <net/checksum.h> 34#include <net/checksum.h>
35#include <asm/checksum.h> 35#include <asm/checksum.h>
36#include <linux/module.h>
36 37
37static inline unsigned short from32to16(unsigned long x) 38static inline unsigned short from32to16(unsigned long x)
38{ 39{
@@ -115,34 +116,52 @@ unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum)
115 return result; 116 return result;
116} 117}
117 118
119EXPORT_SYMBOL(csum_partial);
120
118/* 121/*
119 * this routine is used for miscellaneous IP-like checksums, mainly 122 * this routine is used for miscellaneous IP-like checksums, mainly
120 * in icmp.c 123 * in icmp.c
121 */ 124 */
122unsigned short ip_compute_csum(const unsigned char * buff, int len) 125unsigned short ip_compute_csum(const unsigned char * buff, int len)
123{ 126{
124 return ~do_csum(buff,len); 127 return ~do_csum(buff, len);
125} 128}
126 129
130EXPORT_SYMBOL(ip_compute_csum);
131
127/* 132/*
128 * copy from fs while checksumming, otherwise like csum_partial 133 * copy from fs while checksumming, otherwise like csum_partial
129 */ 134 */
130
131unsigned int 135unsigned int
132csum_partial_copy_from_user(const char *src, char *dst, int len, int sum, int *csum_err) 136csum_partial_copy_from_user(const char __user *src, char *dst,
137 int len, int sum, int *csum_err)
133{ 138{
134 if (csum_err) *csum_err = 0; 139 int rem;
135 memcpy(dst, src, len); 140
141 if (csum_err)
142 *csum_err = 0;
143
144 rem = copy_from_user(dst, src, len);
145 if (rem != 0) {
146 if (csum_err)
147 *csum_err = -EFAULT;
148 memset(dst + len - rem, 0, rem);
149 len = rem;
150 }
151
136 return csum_partial(dst, len, sum); 152 return csum_partial(dst, len, sum);
137} 153}
138 154
155EXPORT_SYMBOL(csum_partial_copy_from_user);
156
139/* 157/*
140 * copy from ds while checksumming, otherwise like csum_partial 158 * copy from ds while checksumming, otherwise like csum_partial
141 */ 159 */
142
143unsigned int 160unsigned int
144csum_partial_copy(const char *src, char *dst, int len, int sum) 161csum_partial_copy(const char *src, char *dst, int len, int sum)
145{ 162{
146 memcpy(dst, src, len); 163 memcpy(dst, src, len);
147 return csum_partial(dst, len, sum); 164 return csum_partial(dst, len, sum);
148} 165}
166
167EXPORT_SYMBOL(csum_partial_copy);
diff --git a/arch/frv/mb93090-mb00/Makefile b/arch/frv/mb93090-mb00/Makefile
index 3faf0f8cf9..76595e8707 100644
--- a/arch/frv/mb93090-mb00/Makefile
+++ b/arch/frv/mb93090-mb00/Makefile
@@ -3,7 +3,7 @@
3# 3#
4 4
5ifeq "$(CONFIG_PCI)" "y" 5ifeq "$(CONFIG_PCI)" "y"
6obj-y := pci-frv.o pci-irq.o pci-vdk.o 6obj-y := pci-frv.o pci-irq.o pci-vdk.o pci-iomap.o
7 7
8ifeq "$(CONFIG_MMU)" "y" 8ifeq "$(CONFIG_MMU)" "y"
9obj-y += pci-dma.o 9obj-y += pci-dma.o
diff --git a/arch/frv/mb93090-mb00/pci-dma-nommu.c b/arch/frv/mb93090-mb00/pci-dma-nommu.c
index 2082a9647f..4985466b1a 100644
--- a/arch/frv/mb93090-mb00/pci-dma-nommu.c
+++ b/arch/frv/mb93090-mb00/pci-dma-nommu.c
@@ -83,6 +83,8 @@ void *dma_alloc_coherent(struct device *hwdev, size_t size, dma_addr_t *dma_hand
83 return NULL; 83 return NULL;
84} 84}
85 85
86EXPORT_SYMBOL(dma_alloc_coherent);
87
86void dma_free_coherent(struct device *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle) 88void dma_free_coherent(struct device *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle)
87{ 89{
88 struct dma_alloc_record *rec; 90 struct dma_alloc_record *rec;
@@ -102,6 +104,8 @@ void dma_free_coherent(struct device *hwdev, size_t size, void *vaddr, dma_addr_
102 BUG(); 104 BUG();
103} 105}
104 106
107EXPORT_SYMBOL(dma_free_coherent);
108
105/* 109/*
106 * Map a single buffer of the indicated size for DMA in streaming mode. 110 * Map a single buffer of the indicated size for DMA in streaming mode.
107 * The 32-bit bus address to use is returned. 111 * The 32-bit bus address to use is returned.
@@ -120,6 +124,8 @@ dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
120 return virt_to_bus(ptr); 124 return virt_to_bus(ptr);
121} 125}
122 126
127EXPORT_SYMBOL(dma_map_single);
128
123/* 129/*
124 * Map a set of buffers described by scatterlist in streaming 130 * Map a set of buffers described by scatterlist in streaming
125 * mode for DMA. This is the scather-gather version of the 131 * mode for DMA. This is the scather-gather version of the
@@ -150,3 +156,5 @@ int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
150 156
151 return nents; 157 return nents;
152} 158}
159
160EXPORT_SYMBOL(dma_map_sg);
diff --git a/arch/frv/mb93090-mb00/pci-dma.c b/arch/frv/mb93090-mb00/pci-dma.c
index 86fbdadc51..671ce1e843 100644
--- a/arch/frv/mb93090-mb00/pci-dma.c
+++ b/arch/frv/mb93090-mb00/pci-dma.c
@@ -28,11 +28,15 @@ void *dma_alloc_coherent(struct device *hwdev, size_t size, dma_addr_t *dma_hand
28 return ret; 28 return ret;
29} 29}
30 30
31EXPORT_SYMBOL(dma_alloc_coherent);
32
31void dma_free_coherent(struct device *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle) 33void dma_free_coherent(struct device *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle)
32{ 34{
33 consistent_free(vaddr); 35 consistent_free(vaddr);
34} 36}
35 37
38EXPORT_SYMBOL(dma_free_coherent);
39
36/* 40/*
37 * Map a single buffer of the indicated size for DMA in streaming mode. 41 * Map a single buffer of the indicated size for DMA in streaming mode.
38 * The 32-bit bus address to use is returned. 42 * The 32-bit bus address to use is returned.
@@ -51,6 +55,8 @@ dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
51 return virt_to_bus(ptr); 55 return virt_to_bus(ptr);
52} 56}
53 57
58EXPORT_SYMBOL(dma_map_single);
59
54/* 60/*
55 * Map a set of buffers described by scatterlist in streaming 61 * Map a set of buffers described by scatterlist in streaming
56 * mode for DMA. This is the scather-gather version of the 62 * mode for DMA. This is the scather-gather version of the
@@ -96,6 +102,8 @@ int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
96 return nents; 102 return nents;
97} 103}
98 104
105EXPORT_SYMBOL(dma_map_sg);
106
99dma_addr_t dma_map_page(struct device *dev, struct page *page, unsigned long offset, 107dma_addr_t dma_map_page(struct device *dev, struct page *page, unsigned long offset,
100 size_t size, enum dma_data_direction direction) 108 size_t size, enum dma_data_direction direction)
101{ 109{
@@ -103,3 +111,5 @@ dma_addr_t dma_map_page(struct device *dev, struct page *page, unsigned long off
103 flush_dcache_page(page); 111 flush_dcache_page(page);
104 return (dma_addr_t) page_to_phys(page) + offset; 112 return (dma_addr_t) page_to_phys(page) + offset;
105} 113}
114
115EXPORT_SYMBOL(dma_map_page);
diff --git a/arch/frv/mb93090-mb00/pci-frv.c b/arch/frv/mb93090-mb00/pci-frv.c
index 83e5489cf0..0a26bf6f1c 100644
--- a/arch/frv/mb93090-mb00/pci-frv.c
+++ b/arch/frv/mb93090-mb00/pci-frv.c
@@ -142,9 +142,7 @@ static void __init pcibios_allocate_resources(int pass)
142 u16 command; 142 u16 command;
143 struct resource *r, *pr; 143 struct resource *r, *pr;
144 144
145 while (dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev), 145 for_each_pci_dev(dev) {
146 dev != NULL
147 ) {
148 pci_read_config_word(dev, PCI_COMMAND, &command); 146 pci_read_config_word(dev, PCI_COMMAND, &command);
149 for(idx = 0; idx < 6; idx++) { 147 for(idx = 0; idx < 6; idx++) {
150 r = &dev->resource[idx]; 148 r = &dev->resource[idx];
@@ -188,9 +186,7 @@ static void __init pcibios_assign_resources(void)
188 int idx; 186 int idx;
189 struct resource *r; 187 struct resource *r;
190 188
191 while (dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev), 189 for_each_pci_dev(dev) {
192 dev != NULL
193 ) {
194 int class = dev->class >> 8; 190 int class = dev->class >> 8;
195 191
196 /* Don't touch classless devices and host bridges */ 192 /* Don't touch classless devices and host bridges */
diff --git a/arch/frv/mb93090-mb00/pci-iomap.c b/arch/frv/mb93090-mb00/pci-iomap.c
new file mode 100644
index 0000000000..068fa04bd5
--- /dev/null
+++ b/arch/frv/mb93090-mb00/pci-iomap.c
@@ -0,0 +1,29 @@
1/* pci-iomap.c: description
2 *
3 * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11#include <linux/pci.h>
12#include <linux/module.h>
13
14void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen)
15{
16 unsigned long start = pci_resource_start(dev, bar);
17 unsigned long len = pci_resource_len(dev, bar);
18 unsigned long flags = pci_resource_flags(dev, bar);
19
20 if (!len || !start)
21 return NULL;
22
23 if ((flags & IORESOURCE_IO) || (flags & IORESOURCE_MEM))
24 return (void __iomem *) start;
25
26 return NULL;
27}
28
29EXPORT_SYMBOL(pci_iomap);
diff --git a/arch/frv/mb93090-mb00/pci-irq.c b/arch/frv/mb93090-mb00/pci-irq.c
index af981bda01..c4a1144c98 100644
--- a/arch/frv/mb93090-mb00/pci-irq.c
+++ b/arch/frv/mb93090-mb00/pci-irq.c
@@ -48,9 +48,7 @@ void __init pcibios_fixup_irqs(void)
48 struct pci_dev *dev = NULL; 48 struct pci_dev *dev = NULL;
49 uint8_t line, pin; 49 uint8_t line, pin;
50 50
51 while (dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev), 51 for_each_pci_dev(dev) {
52 dev != NULL
53 ) {
54 pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); 52 pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
55 if (pin) { 53 if (pin) {
56 dev->irq = pci_bus0_irq_routing[PCI_SLOT(dev->devfn)][pin - 1]; 54 dev->irq = pci_bus0_irq_routing[PCI_SLOT(dev->devfn)][pin - 1];
@@ -60,7 +58,7 @@ void __init pcibios_fixup_irqs(void)
60 } 58 }
61} 59}
62 60
63void __init pcibios_penalize_isa_irq(int irq, int active) 61void __init pcibios_penalize_isa_irq(int irq)
64{ 62{
65} 63}
66 64
diff --git a/arch/frv/mm/cache-page.c b/arch/frv/mm/cache-page.c
index 683b5e3443..0261cbe153 100644
--- a/arch/frv/mm/cache-page.c
+++ b/arch/frv/mm/cache-page.c
@@ -11,6 +11,7 @@
11#include <linux/sched.h> 11#include <linux/sched.h>
12#include <linux/mm.h> 12#include <linux/mm.h>
13#include <linux/highmem.h> 13#include <linux/highmem.h>
14#include <linux/module.h>
14#include <asm/pgalloc.h> 15#include <asm/pgalloc.h>
15 16
16/*****************************************************************************/ 17/*****************************************************************************/
@@ -38,6 +39,8 @@ void flush_dcache_page(struct page *page)
38 39
39} /* end flush_dcache_page() */ 40} /* end flush_dcache_page() */
40 41
42EXPORT_SYMBOL(flush_dcache_page);
43
41/*****************************************************************************/ 44/*****************************************************************************/
42/* 45/*
43 * ICI takes a virtual address and the page may not currently have one 46 * ICI takes a virtual address and the page may not currently have one
@@ -64,3 +67,5 @@ void flush_icache_user_range(struct vm_area_struct *vma, struct page *page,
64 } 67 }
65 68
66} /* end flush_icache_user_range() */ 69} /* end flush_icache_user_range() */
70
71EXPORT_SYMBOL(flush_icache_user_range);
diff --git a/arch/frv/mm/extable.c b/arch/frv/mm/extable.c
index 41be1128dc..caacf030ac 100644
--- a/arch/frv/mm/extable.c
+++ b/arch/frv/mm/extable.c
@@ -43,7 +43,7 @@ static inline unsigned long search_one_table(const struct exception_table_entry
43 */ 43 */
44unsigned long search_exception_table(unsigned long pc) 44unsigned long search_exception_table(unsigned long pc)
45{ 45{
46 unsigned long ret = 0; 46 const struct exception_table_entry *extab;
47 47
48 /* determine if the fault lay during a memcpy_user or a memset_user */ 48 /* determine if the fault lay during a memcpy_user or a memset_user */
49 if (__frame->lr == (unsigned long) &__memset_user_error_lr && 49 if (__frame->lr == (unsigned long) &__memset_user_error_lr &&
@@ -55,9 +55,10 @@ unsigned long search_exception_table(unsigned long pc)
55 */ 55 */
56 return (unsigned long) &__memset_user_error_handler; 56 return (unsigned long) &__memset_user_error_handler;
57 } 57 }
58 else if (__frame->lr == (unsigned long) &__memcpy_user_error_lr && 58
59 (unsigned long) &memcpy <= pc && pc < (unsigned long) &__memcpy_end 59 if (__frame->lr == (unsigned long) &__memcpy_user_error_lr &&
60 ) { 60 (unsigned long) &memcpy <= pc && pc < (unsigned long) &__memcpy_end
61 ) {
61 /* the fault occurred in a protected memset 62 /* the fault occurred in a protected memset
62 * - we search for the return address (in LR) instead of the program counter 63 * - we search for the return address (in LR) instead of the program counter
63 * - it was probably during a copy_to/from_user() 64 * - it was probably during a copy_to/from_user()
@@ -65,27 +66,10 @@ unsigned long search_exception_table(unsigned long pc)
65 return (unsigned long) &__memcpy_user_error_handler; 66 return (unsigned long) &__memcpy_user_error_handler;
66 } 67 }
67 68
68#ifndef CONFIG_MODULES 69 extab = search_exception_tables(pc);
69 /* there is only the kernel to search. */ 70 if (extab)
70 ret = search_one_table(__start___ex_table, __stop___ex_table - 1, pc); 71 return extab->fixup;
71 return ret;
72
73#else
74 /* the kernel is the last "module" -- no need to treat it special */
75 unsigned long flags;
76 struct module *mp;
77 72
78 spin_lock_irqsave(&modlist_lock, flags); 73 return 0;
79
80 for (mp = module_list; mp != NULL; mp = mp->next) {
81 if (mp->ex_table_start == NULL || !(mp->flags & (MOD_RUNNING | MOD_INITIALIZING)))
82 continue;
83 ret = search_one_table(mp->ex_table_start, mp->ex_table_end - 1, pc);
84 if (ret)
85 break;
86 }
87 74
88 spin_unlock_irqrestore(&modlist_lock, flags);
89 return ret;
90#endif
91} /* end search_exception_table() */ 75} /* end search_exception_table() */
diff --git a/arch/frv/mm/highmem.c b/arch/frv/mm/highmem.c
index 7dc8fbf3af..7f77db7fab 100644
--- a/arch/frv/mm/highmem.c
+++ b/arch/frv/mm/highmem.c
@@ -9,6 +9,7 @@
9 * 2 of the License, or (at your option) any later version. 9 * 2 of the License, or (at your option) any later version.
10 */ 10 */
11#include <linux/highmem.h> 11#include <linux/highmem.h>
12#include <linux/module.h>
12 13
13void *kmap(struct page *page) 14void *kmap(struct page *page)
14{ 15{
@@ -18,6 +19,8 @@ void *kmap(struct page *page)
18 return kmap_high(page); 19 return kmap_high(page);
19} 20}
20 21
22EXPORT_SYMBOL(kmap);
23
21void kunmap(struct page *page) 24void kunmap(struct page *page)
22{ 25{
23 if (in_interrupt()) 26 if (in_interrupt())
@@ -27,7 +30,12 @@ void kunmap(struct page *page)
27 kunmap_high(page); 30 kunmap_high(page);
28} 31}
29 32
33EXPORT_SYMBOL(kunmap);
34
30struct page *kmap_atomic_to_page(void *ptr) 35struct page *kmap_atomic_to_page(void *ptr)
31{ 36{
32 return virt_to_page(ptr); 37 return virt_to_page(ptr);
33} 38}
39
40
41EXPORT_SYMBOL(kmap_atomic_to_page);
diff --git a/arch/frv/mm/init.c b/arch/frv/mm/init.c
index 79433159b5..765088ea8a 100644
--- a/arch/frv/mm/init.c
+++ b/arch/frv/mm/init.c
@@ -108,7 +108,7 @@ void __init paging_init(void)
108 108
109 memset((void *) empty_zero_page, 0, PAGE_SIZE); 109 memset((void *) empty_zero_page, 0, PAGE_SIZE);
110 110
111#if CONFIG_HIGHMEM 111#ifdef CONFIG_HIGHMEM
112 if (num_physpages - num_mappedpages) { 112 if (num_physpages - num_mappedpages) {
113 pgd_t *pge; 113 pgd_t *pge;
114 pud_t *pue; 114 pud_t *pue;
diff --git a/arch/frv/mm/pgalloc.c b/arch/frv/mm/pgalloc.c
index 2c67dfe5a6..f76dd03ddd 100644
--- a/arch/frv/mm/pgalloc.c
+++ b/arch/frv/mm/pgalloc.c
@@ -85,7 +85,7 @@ static inline void pgd_list_add(pgd_t *pgd)
85 struct page *page = virt_to_page(pgd); 85 struct page *page = virt_to_page(pgd);
86 page->index = (unsigned long) pgd_list; 86 page->index = (unsigned long) pgd_list;
87 if (pgd_list) 87 if (pgd_list)
88 pgd_list->private = (unsigned long) &page->index; 88 set_page_private(pgd_list, (unsigned long) &page->index);
89 pgd_list = page; 89 pgd_list = page;
90 set_page_private(page, (unsigned long)&pgd_list); 90 set_page_private(page, (unsigned long)&pgd_list);
91} 91}
@@ -94,10 +94,10 @@ static inline void pgd_list_del(pgd_t *pgd)
94{ 94{
95 struct page *next, **pprev, *page = virt_to_page(pgd); 95 struct page *next, **pprev, *page = virt_to_page(pgd);
96 next = (struct page *) page->index; 96 next = (struct page *) page->index;
97 pprev = (struct page **)page_private(page); 97 pprev = (struct page **) page_private(page);
98 *pprev = next; 98 *pprev = next;
99 if (next) 99 if (next)
100 next->private = (unsigned long) pprev; 100 set_page_private(next, (unsigned long) pprev);
101} 101}
102 102
103void pgd_ctor(void *pgd, kmem_cache_t *cache, unsigned long unused) 103void pgd_ctor(void *pgd, kmem_cache_t *cache, unsigned long unused)