aboutsummaryrefslogtreecommitdiffstats
path: root/include/asm-arm
diff options
context:
space:
mode:
Diffstat (limited to 'include/asm-arm')
-rw-r--r--include/asm-arm/arch-imx/imxfb.h1
-rw-r--r--include/asm-arm/arch-s3c2410/regs-iis.h10
-rw-r--r--include/asm-arm/arch-shark/io.h147
-rw-r--r--include/asm-arm/bitops.h9
-rw-r--r--include/asm-arm/emergency-restart.h6
-rw-r--r--include/asm-arm/locks.h40
-rw-r--r--include/asm-arm/smp.h3
-rw-r--r--include/asm-arm/spinlock.h82
-rw-r--r--include/asm-arm/system.h92
9 files changed, 165 insertions, 225 deletions
diff --git a/include/asm-arm/arch-imx/imxfb.h b/include/asm-arm/arch-imx/imxfb.h
index 2346d454ab9c..7dbc7bbba65d 100644
--- a/include/asm-arm/arch-imx/imxfb.h
+++ b/include/asm-arm/arch-imx/imxfb.h
@@ -25,6 +25,7 @@ struct imxfb_mach_info {
25 u_int pcr; 25 u_int pcr;
26 u_int pwmr; 26 u_int pwmr;
27 u_int lscr1; 27 u_int lscr1;
28 u_int dmacr;
28 29
29 u_char * fixed_screen_cpu; 30 u_char * fixed_screen_cpu;
30 dma_addr_t fixed_screen_dma; 31 dma_addr_t fixed_screen_dma;
diff --git a/include/asm-arm/arch-s3c2410/regs-iis.h b/include/asm-arm/arch-s3c2410/regs-iis.h
index 385b07d510da..fdd62e8cd6cb 100644
--- a/include/asm-arm/arch-s3c2410/regs-iis.h
+++ b/include/asm-arm/arch-s3c2410/regs-iis.h
@@ -15,6 +15,9 @@
15 * 12-03-2004 BJD Updated include protection 15 * 12-03-2004 BJD Updated include protection
16 * 07-03-2005 BJD Added FIFO size flags and S3C2440 MPLL 16 * 07-03-2005 BJD Added FIFO size flags and S3C2440 MPLL
17 * 05-04-2005 LCVR Added IISFCON definitions for the S3C2400 17 * 05-04-2005 LCVR Added IISFCON definitions for the S3C2400
18 * 18-07-2005 DA Change IISCON_MPLL to IISMOD_MPLL
19 * Correct IISMOD_256FS and IISMOD_384FS
20 * Add IISCON_PSCEN
18 */ 21 */
19 22
20#ifndef __ASM_ARCH_REGS_IIS_H 23#ifndef __ASM_ARCH_REGS_IIS_H
@@ -22,7 +25,6 @@
22 25
23#define S3C2410_IISCON (0x00) 26#define S3C2410_IISCON (0x00)
24 27
25#define S3C2440_IISCON_MPLL (1<<9)
26#define S3C2410_IISCON_LRINDEX (1<<8) 28#define S3C2410_IISCON_LRINDEX (1<<8)
27#define S3C2410_IISCON_TXFIFORDY (1<<7) 29#define S3C2410_IISCON_TXFIFORDY (1<<7)
28#define S3C2410_IISCON_RXFIFORDY (1<<6) 30#define S3C2410_IISCON_RXFIFORDY (1<<6)
@@ -30,10 +32,12 @@
30#define S3C2410_IISCON_RXDMAEN (1<<4) 32#define S3C2410_IISCON_RXDMAEN (1<<4)
31#define S3C2410_IISCON_TXIDLE (1<<3) 33#define S3C2410_IISCON_TXIDLE (1<<3)
32#define S3C2410_IISCON_RXIDLE (1<<2) 34#define S3C2410_IISCON_RXIDLE (1<<2)
35#define S3C2410_IISCON_PSCEN (1<<1)
33#define S3C2410_IISCON_IISEN (1<<0) 36#define S3C2410_IISCON_IISEN (1<<0)
34 37
35#define S3C2410_IISMOD (0x04) 38#define S3C2410_IISMOD (0x04)
36 39
40#define S3C2440_IISMOD_MPLL (1<<9)
37#define S3C2410_IISMOD_SLAVE (1<<8) 41#define S3C2410_IISMOD_SLAVE (1<<8)
38#define S3C2410_IISMOD_NOXFER (0<<6) 42#define S3C2410_IISMOD_NOXFER (0<<6)
39#define S3C2410_IISMOD_RXMODE (1<<6) 43#define S3C2410_IISMOD_RXMODE (1<<6)
@@ -46,8 +50,8 @@
46#define S3C2410_IISMOD_8BIT (0<<3) 50#define S3C2410_IISMOD_8BIT (0<<3)
47#define S3C2410_IISMOD_16BIT (1<<3) 51#define S3C2410_IISMOD_16BIT (1<<3)
48#define S3C2410_IISMOD_BITMASK (1<<3) 52#define S3C2410_IISMOD_BITMASK (1<<3)
49#define S3C2410_IISMOD_256FS (0<<1) 53#define S3C2410_IISMOD_256FS (0<<2)
50#define S3C2410_IISMOD_384FS (1<<1) 54#define S3C2410_IISMOD_384FS (1<<2)
51#define S3C2410_IISMOD_16FS (0<<0) 55#define S3C2410_IISMOD_16FS (0<<0)
52#define S3C2410_IISMOD_32FS (1<<0) 56#define S3C2410_IISMOD_32FS (1<<0)
53#define S3C2410_IISMOD_48FS (2<<0) 57#define S3C2410_IISMOD_48FS (2<<0)
diff --git a/include/asm-arm/arch-shark/io.h b/include/asm-arm/arch-shark/io.h
index 1e7f26bc2e1d..5e6ed0038b2b 100644
--- a/include/asm-arm/arch-shark/io.h
+++ b/include/asm-arm/arch-shark/io.h
@@ -21,38 +21,8 @@
21 */ 21 */
22#define __PORT_PCIO(x) (!((x) & 0x80000000)) 22#define __PORT_PCIO(x) (!((x) & 0x80000000))
23 23
24/* 24#define __io(a) ((void __iomem *)(PCIO_BASE + (a)))
25 * Dynamic IO functions - let the compiler
26 * optimize the expressions
27 */
28#define DECLARE_DYN_OUT(fnsuffix,instr) \
29static inline void __out##fnsuffix (unsigned int value, unsigned int port) \
30{ \
31 unsigned long temp; \
32 __asm__ __volatile__( \
33 "tst %2, #0x80000000\n\t" \
34 "mov %0, %4\n\t" \
35 "addeq %0, %0, %3\n\t" \
36 "str" instr " %1, [%0, %2] @ out" #fnsuffix \
37 : "=&r" (temp) \
38 : "r" (value), "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE) \
39 : "cc"); \
40}
41 25
42#define DECLARE_DYN_IN(sz,fnsuffix,instr) \
43static inline unsigned sz __in##fnsuffix (unsigned int port) \
44{ \
45 unsigned long temp, value; \
46 __asm__ __volatile__( \
47 "tst %2, #0x80000000\n\t" \
48 "mov %0, %4\n\t" \
49 "addeq %0, %0, %3\n\t" \
50 "ldr" instr " %1, [%0, %2] @ in" #fnsuffix \
51 : "=&r" (temp), "=r" (value) \
52 : "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE) \
53 : "cc"); \
54 return (unsigned sz)value; \
55}
56 26
57static inline unsigned int __ioaddr (unsigned int port) \ 27static inline unsigned int __ioaddr (unsigned int port) \
58{ \ 28{ \
@@ -62,123 +32,8 @@ static inline unsigned int __ioaddr (unsigned int port) \
62 return (unsigned int)(IO_BASE + (port)); \ 32 return (unsigned int)(IO_BASE + (port)); \
63} 33}
64 34
65#define DECLARE_IO(sz,fnsuffix,instr) \
66 DECLARE_DYN_OUT(fnsuffix,instr) \
67 DECLARE_DYN_IN(sz,fnsuffix,instr)
68
69DECLARE_IO(char,b,"b")
70DECLARE_IO(short,w,"h")
71DECLARE_IO(long,l,"")
72
73#undef DECLARE_IO
74#undef DECLARE_DYN_OUT
75#undef DECLARE_DYN_IN
76
77/*
78 * Constant address IO functions
79 *
80 * These have to be macros for the 'J' constraint to work -
81 * +/-4096 immediate operand.
82 */
83#define __outbc(value,port) \
84({ \
85 if (__PORT_PCIO((port))) \
86 __asm__ __volatile__( \
87 "strb %0, [%1, %2] @ outbc" \
88 : : "r" (value), "r" (PCIO_BASE), "Jr" (port)); \
89 else \
90 __asm__ __volatile__( \
91 "strb %0, [%1, %2] @ outbc" \
92 : : "r" (value), "r" (IO_BASE), "r" (port)); \
93})
94
95#define __inbc(port) \
96({ \
97 unsigned char result; \
98 if (__PORT_PCIO((port))) \
99 __asm__ __volatile__( \
100 "ldrb %0, [%1, %2] @ inbc" \
101 : "=r" (result) : "r" (PCIO_BASE), "Jr" (port)); \
102 else \
103 __asm__ __volatile__( \
104 "ldrb %0, [%1, %2] @ inbc" \
105 : "=r" (result) : "r" (IO_BASE), "r" (port)); \
106 result; \
107})
108
109#define __outwc(value,port) \
110({ \
111 unsigned long v = value; \
112 if (__PORT_PCIO((port))) \
113 __asm__ __volatile__( \
114 "strh %0, [%1, %2] @ outwc" \
115 : : "r" (v|v<<16), "r" (PCIO_BASE), "Jr" (port)); \
116 else \
117 __asm__ __volatile__( \
118 "strh %0, [%1, %2] @ outwc" \
119 : : "r" (v|v<<16), "r" (IO_BASE), "r" (port)); \
120})
121
122#define __inwc(port) \
123({ \
124 unsigned short result; \
125 if (__PORT_PCIO((port))) \
126 __asm__ __volatile__( \
127 "ldrh %0, [%1, %2] @ inwc" \
128 : "=r" (result) : "r" (PCIO_BASE), "Jr" (port)); \
129 else \
130 __asm__ __volatile__( \
131 "ldrh %0, [%1, %2] @ inwc" \
132 : "=r" (result) : "r" (IO_BASE), "r" (port)); \
133 result & 0xffff; \
134})
135
136#define __outlc(value,port) \
137({ \
138 unsigned long v = value; \
139 if (__PORT_PCIO((port))) \
140 __asm__ __volatile__( \
141 "str %0, [%1, %2] @ outlc" \
142 : : "r" (v), "r" (PCIO_BASE), "Jr" (port)); \
143 else \
144 __asm__ __volatile__( \
145 "str %0, [%1, %2] @ outlc" \
146 : : "r" (v), "r" (IO_BASE), "r" (port)); \
147})
148
149#define __inlc(port) \
150({ \
151 unsigned long result; \
152 if (__PORT_PCIO((port))) \
153 __asm__ __volatile__( \
154 "ldr %0, [%1, %2] @ inlc" \
155 : "=r" (result) : "r" (PCIO_BASE), "Jr" (port)); \
156 else \
157 __asm__ __volatile__( \
158 "ldr %0, [%1, %2] @ inlc" \
159 : "=r" (result) : "r" (IO_BASE), "r" (port)); \
160 result; \
161})
162
163#define __ioaddrc(port) \
164({ \
165 unsigned long addr; \
166 if (__PORT_PCIO((port))) \
167 addr = PCIO_BASE + (port); \
168 else \
169 addr = IO_BASE + (port); \
170 addr; \
171})
172
173#define __mem_pci(addr) (addr) 35#define __mem_pci(addr) (addr)
174 36
175#define inb(p) (__builtin_constant_p((p)) ? __inbc(p) : __inb(p))
176#define inw(p) (__builtin_constant_p((p)) ? __inwc(p) : __inw(p))
177#define inl(p) (__builtin_constant_p((p)) ? __inlc(p) : __inl(p))
178#define outb(v,p) (__builtin_constant_p((p)) ? __outbc(v,p) : __outb(v,p))
179#define outw(v,p) (__builtin_constant_p((p)) ? __outwc(v,p) : __outw(v,p))
180#define outl(v,p) (__builtin_constant_p((p)) ? __outlc(v,p) : __outl(v,p))
181
182/* 37/*
183 * Translated address IO functions 38 * Translated address IO functions
184 * 39 *
diff --git a/include/asm-arm/bitops.h b/include/asm-arm/bitops.h
index 4edd4dc40c5b..aad7aad026b3 100644
--- a/include/asm-arm/bitops.h
+++ b/include/asm-arm/bitops.h
@@ -21,8 +21,8 @@
21 21
22#include <asm/system.h> 22#include <asm/system.h>
23 23
24#define smp_mb__before_clear_bit() do { } while (0) 24#define smp_mb__before_clear_bit() mb()
25#define smp_mb__after_clear_bit() do { } while (0) 25#define smp_mb__after_clear_bit() mb()
26 26
27/* 27/*
28 * These functions are the basis of our bit ops. 28 * These functions are the basis of our bit ops.
@@ -229,6 +229,7 @@ extern int _find_next_zero_bit_be(const void * p, int size, int offset);
229extern int _find_first_bit_be(const unsigned long *p, unsigned size); 229extern int _find_first_bit_be(const unsigned long *p, unsigned size);
230extern int _find_next_bit_be(const unsigned long *p, int size, int offset); 230extern int _find_next_bit_be(const unsigned long *p, int size, int offset);
231 231
232#ifndef CONFIG_SMP
232/* 233/*
233 * The __* form of bitops are non-atomic and may be reordered. 234 * The __* form of bitops are non-atomic and may be reordered.
234 */ 235 */
@@ -241,6 +242,10 @@ extern int _find_next_bit_be(const unsigned long *p, int size, int offset);
241 (__builtin_constant_p(nr) ? \ 242 (__builtin_constant_p(nr) ? \
242 ____atomic_##name(nr, p) : \ 243 ____atomic_##name(nr, p) : \
243 _##name##_be(nr,p)) 244 _##name##_be(nr,p))
245#else
246#define ATOMIC_BITOP_LE(name,nr,p) _##name##_le(nr,p)
247#define ATOMIC_BITOP_BE(name,nr,p) _##name##_be(nr,p)
248#endif
244 249
245#define NONATOMIC_BITOP(name,nr,p) \ 250#define NONATOMIC_BITOP(name,nr,p) \
246 (____nonatomic_##name(nr, p)) 251 (____nonatomic_##name(nr, p))
diff --git a/include/asm-arm/emergency-restart.h b/include/asm-arm/emergency-restart.h
new file mode 100644
index 000000000000..108d8c48e42e
--- /dev/null
+++ b/include/asm-arm/emergency-restart.h
@@ -0,0 +1,6 @@
1#ifndef _ASM_EMERGENCY_RESTART_H
2#define _ASM_EMERGENCY_RESTART_H
3
4#include <asm-generic/emergency-restart.h>
5
6#endif /* _ASM_EMERGENCY_RESTART_H */
diff --git a/include/asm-arm/locks.h b/include/asm-arm/locks.h
index c26298f3891f..f08dc8447913 100644
--- a/include/asm-arm/locks.h
+++ b/include/asm-arm/locks.h
@@ -28,7 +28,8 @@
28" blmi " #fail \ 28" blmi " #fail \
29 : \ 29 : \
30 : "r" (ptr), "I" (1) \ 30 : "r" (ptr), "I" (1) \
31 : "ip", "lr", "cc", "memory"); \ 31 : "ip", "lr", "cc"); \
32 smp_mb(); \
32 }) 33 })
33 34
34#define __down_op_ret(ptr,fail) \ 35#define __down_op_ret(ptr,fail) \
@@ -48,12 +49,14 @@
48" mov %0, ip" \ 49" mov %0, ip" \
49 : "=&r" (ret) \ 50 : "=&r" (ret) \
50 : "r" (ptr), "I" (1) \ 51 : "r" (ptr), "I" (1) \
51 : "ip", "lr", "cc", "memory"); \ 52 : "ip", "lr", "cc"); \
53 smp_mb(); \
52 ret; \ 54 ret; \
53 }) 55 })
54 56
55#define __up_op(ptr,wake) \ 57#define __up_op(ptr,wake) \
56 ({ \ 58 ({ \
59 smp_mb(); \
57 __asm__ __volatile__( \ 60 __asm__ __volatile__( \
58 "@ up_op\n" \ 61 "@ up_op\n" \
59"1: ldrex lr, [%0]\n" \ 62"1: ldrex lr, [%0]\n" \
@@ -61,12 +64,12 @@
61" strex ip, lr, [%0]\n" \ 64" strex ip, lr, [%0]\n" \
62" teq ip, #0\n" \ 65" teq ip, #0\n" \
63" bne 1b\n" \ 66" bne 1b\n" \
64" teq lr, #0\n" \ 67" cmp lr, #0\n" \
65" movle ip, %0\n" \ 68" movle ip, %0\n" \
66" blle " #wake \ 69" blle " #wake \
67 : \ 70 : \
68 : "r" (ptr), "I" (1) \ 71 : "r" (ptr), "I" (1) \
69 : "ip", "lr", "cc", "memory"); \ 72 : "ip", "lr", "cc"); \
70 }) 73 })
71 74
72/* 75/*
@@ -92,15 +95,17 @@
92" blne " #fail \ 95" blne " #fail \
93 : \ 96 : \
94 : "r" (ptr), "I" (RW_LOCK_BIAS) \ 97 : "r" (ptr), "I" (RW_LOCK_BIAS) \
95 : "ip", "lr", "cc", "memory"); \ 98 : "ip", "lr", "cc"); \
99 smp_mb(); \
96 }) 100 })
97 101
98#define __up_op_write(ptr,wake) \ 102#define __up_op_write(ptr,wake) \
99 ({ \ 103 ({ \
104 smp_mb(); \
100 __asm__ __volatile__( \ 105 __asm__ __volatile__( \
101 "@ up_op_read\n" \ 106 "@ up_op_read\n" \
102"1: ldrex lr, [%0]\n" \ 107"1: ldrex lr, [%0]\n" \
103" add lr, lr, %1\n" \ 108" adds lr, lr, %1\n" \
104" strex ip, lr, [%0]\n" \ 109" strex ip, lr, [%0]\n" \
105" teq ip, #0\n" \ 110" teq ip, #0\n" \
106" bne 1b\n" \ 111" bne 1b\n" \
@@ -108,7 +113,7 @@
108" blcs " #wake \ 113" blcs " #wake \
109 : \ 114 : \
110 : "r" (ptr), "I" (RW_LOCK_BIAS) \ 115 : "r" (ptr), "I" (RW_LOCK_BIAS) \
111 : "ip", "lr", "cc", "memory"); \ 116 : "ip", "lr", "cc"); \
112 }) 117 })
113 118
114#define __down_op_read(ptr,fail) \ 119#define __down_op_read(ptr,fail) \
@@ -116,6 +121,7 @@
116 121
117#define __up_op_read(ptr,wake) \ 122#define __up_op_read(ptr,wake) \
118 ({ \ 123 ({ \
124 smp_mb(); \
119 __asm__ __volatile__( \ 125 __asm__ __volatile__( \
120 "@ up_op_read\n" \ 126 "@ up_op_read\n" \
121"1: ldrex lr, [%0]\n" \ 127"1: ldrex lr, [%0]\n" \
@@ -128,7 +134,7 @@
128" bleq " #wake \ 134" bleq " #wake \
129 : \ 135 : \
130 : "r" (ptr), "I" (1) \ 136 : "r" (ptr), "I" (1) \
131 : "ip", "lr", "cc", "memory"); \ 137 : "ip", "lr", "cc"); \
132 }) 138 })
133 139
134#else 140#else
@@ -148,7 +154,8 @@
148" blmi " #fail \ 154" blmi " #fail \
149 : \ 155 : \
150 : "r" (ptr), "I" (1) \ 156 : "r" (ptr), "I" (1) \
151 : "ip", "lr", "cc", "memory"); \ 157 : "ip", "lr", "cc"); \
158 smp_mb(); \
152 }) 159 })
153 160
154#define __down_op_ret(ptr,fail) \ 161#define __down_op_ret(ptr,fail) \
@@ -169,12 +176,14 @@
169" mov %0, ip" \ 176" mov %0, ip" \
170 : "=&r" (ret) \ 177 : "=&r" (ret) \
171 : "r" (ptr), "I" (1) \ 178 : "r" (ptr), "I" (1) \
172 : "ip", "lr", "cc", "memory"); \ 179 : "ip", "lr", "cc"); \
180 smp_mb(); \
173 ret; \ 181 ret; \
174 }) 182 })
175 183
176#define __up_op(ptr,wake) \ 184#define __up_op(ptr,wake) \
177 ({ \ 185 ({ \
186 smp_mb(); \
178 __asm__ __volatile__( \ 187 __asm__ __volatile__( \
179 "@ up_op\n" \ 188 "@ up_op\n" \
180" mrs ip, cpsr\n" \ 189" mrs ip, cpsr\n" \
@@ -188,7 +197,7 @@
188" blle " #wake \ 197" blle " #wake \
189 : \ 198 : \
190 : "r" (ptr), "I" (1) \ 199 : "r" (ptr), "I" (1) \
191 : "ip", "lr", "cc", "memory"); \ 200 : "ip", "lr", "cc"); \
192 }) 201 })
193 202
194/* 203/*
@@ -215,7 +224,8 @@
215" blne " #fail \ 224" blne " #fail \
216 : \ 225 : \
217 : "r" (ptr), "I" (RW_LOCK_BIAS) \ 226 : "r" (ptr), "I" (RW_LOCK_BIAS) \
218 : "ip", "lr", "cc", "memory"); \ 227 : "ip", "lr", "cc"); \
228 smp_mb(); \
219 }) 229 })
220 230
221#define __up_op_write(ptr,wake) \ 231#define __up_op_write(ptr,wake) \
@@ -233,7 +243,8 @@
233" blcs " #wake \ 243" blcs " #wake \
234 : \ 244 : \
235 : "r" (ptr), "I" (RW_LOCK_BIAS) \ 245 : "r" (ptr), "I" (RW_LOCK_BIAS) \
236 : "ip", "lr", "cc", "memory"); \ 246 : "ip", "lr", "cc"); \
247 smp_mb(); \
237 }) 248 })
238 249
239#define __down_op_read(ptr,fail) \ 250#define __down_op_read(ptr,fail) \
@@ -241,6 +252,7 @@
241 252
242#define __up_op_read(ptr,wake) \ 253#define __up_op_read(ptr,wake) \
243 ({ \ 254 ({ \
255 smp_mb(); \
244 __asm__ __volatile__( \ 256 __asm__ __volatile__( \
245 "@ up_op_read\n" \ 257 "@ up_op_read\n" \
246" mrs ip, cpsr\n" \ 258" mrs ip, cpsr\n" \
@@ -254,7 +266,7 @@
254" bleq " #wake \ 266" bleq " #wake \
255 : \ 267 : \
256 : "r" (ptr), "I" (1) \ 268 : "r" (ptr), "I" (1) \
257 : "ip", "lr", "cc", "memory"); \ 269 : "ip", "lr", "cc"); \
258 }) 270 })
259 271
260#endif 272#endif
diff --git a/include/asm-arm/smp.h b/include/asm-arm/smp.h
index 6c6c60adbbaa..dbb4d859c586 100644
--- a/include/asm-arm/smp.h
+++ b/include/asm-arm/smp.h
@@ -23,9 +23,6 @@
23 23
24#define raw_smp_processor_id() (current_thread_info()->cpu) 24#define raw_smp_processor_id() (current_thread_info()->cpu)
25 25
26extern cpumask_t cpu_present_mask;
27#define cpu_possible_map cpu_present_mask
28
29/* 26/*
30 * at the moment, there's not a big penalty for changing CPUs 27 * at the moment, there's not a big penalty for changing CPUs
31 * (the >big< penalty is running SMP in the first place) 28 * (the >big< penalty is running SMP in the first place)
diff --git a/include/asm-arm/spinlock.h b/include/asm-arm/spinlock.h
index 182323619caa..1f906d09b688 100644
--- a/include/asm-arm/spinlock.h
+++ b/include/asm-arm/spinlock.h
@@ -8,9 +8,10 @@
8/* 8/*
9 * ARMv6 Spin-locking. 9 * ARMv6 Spin-locking.
10 * 10 *
11 * We (exclusively) read the old value, and decrement it. If it 11 * We exclusively read the old value. If it is zero, we may have
12 * hits zero, we may have won the lock, so we try (exclusively) 12 * won the lock, so we try exclusively storing it. A memory barrier
13 * storing it. 13 * is required after we get a lock, and before we release it, because
14 * V6 CPUs are assumed to have weakly ordered memory.
14 * 15 *
15 * Unlocked value: 0 16 * Unlocked value: 0
16 * Locked value: 1 17 * Locked value: 1
@@ -41,7 +42,9 @@ static inline void _raw_spin_lock(spinlock_t *lock)
41" bne 1b" 42" bne 1b"
42 : "=&r" (tmp) 43 : "=&r" (tmp)
43 : "r" (&lock->lock), "r" (1) 44 : "r" (&lock->lock), "r" (1)
44 : "cc", "memory"); 45 : "cc");
46
47 smp_mb();
45} 48}
46 49
47static inline int _raw_spin_trylock(spinlock_t *lock) 50static inline int _raw_spin_trylock(spinlock_t *lock)
@@ -54,18 +57,25 @@ static inline int _raw_spin_trylock(spinlock_t *lock)
54" strexeq %0, %2, [%1]" 57" strexeq %0, %2, [%1]"
55 : "=&r" (tmp) 58 : "=&r" (tmp)
56 : "r" (&lock->lock), "r" (1) 59 : "r" (&lock->lock), "r" (1)
57 : "cc", "memory"); 60 : "cc");
58 61
59 return tmp == 0; 62 if (tmp == 0) {
63 smp_mb();
64 return 1;
65 } else {
66 return 0;
67 }
60} 68}
61 69
62static inline void _raw_spin_unlock(spinlock_t *lock) 70static inline void _raw_spin_unlock(spinlock_t *lock)
63{ 71{
72 smp_mb();
73
64 __asm__ __volatile__( 74 __asm__ __volatile__(
65" str %1, [%0]" 75" str %1, [%0]"
66 : 76 :
67 : "r" (&lock->lock), "r" (0) 77 : "r" (&lock->lock), "r" (0)
68 : "cc", "memory"); 78 : "cc");
69} 79}
70 80
71/* 81/*
@@ -79,7 +89,8 @@ typedef struct {
79} rwlock_t; 89} rwlock_t;
80 90
81#define RW_LOCK_UNLOCKED (rwlock_t) { 0 } 91#define RW_LOCK_UNLOCKED (rwlock_t) { 0 }
82#define rwlock_init(x) do { *(x) + RW_LOCK_UNLOCKED; } while (0) 92#define rwlock_init(x) do { *(x) = RW_LOCK_UNLOCKED; } while (0)
93#define rwlock_is_locked(x) (*((volatile unsigned int *)(x)) != 0)
83 94
84/* 95/*
85 * Write locks are easy - we just set bit 31. When unlocking, we can 96 * Write locks are easy - we just set bit 31. When unlocking, we can
@@ -97,16 +108,40 @@ static inline void _raw_write_lock(rwlock_t *rw)
97" bne 1b" 108" bne 1b"
98 : "=&r" (tmp) 109 : "=&r" (tmp)
99 : "r" (&rw->lock), "r" (0x80000000) 110 : "r" (&rw->lock), "r" (0x80000000)
100 : "cc", "memory"); 111 : "cc");
112
113 smp_mb();
114}
115
116static inline int _raw_write_trylock(rwlock_t *rw)
117{
118 unsigned long tmp;
119
120 __asm__ __volatile__(
121"1: ldrex %0, [%1]\n"
122" teq %0, #0\n"
123" strexeq %0, %2, [%1]"
124 : "=&r" (tmp)
125 : "r" (&rw->lock), "r" (0x80000000)
126 : "cc");
127
128 if (tmp == 0) {
129 smp_mb();
130 return 1;
131 } else {
132 return 0;
133 }
101} 134}
102 135
103static inline void _raw_write_unlock(rwlock_t *rw) 136static inline void _raw_write_unlock(rwlock_t *rw)
104{ 137{
138 smp_mb();
139
105 __asm__ __volatile__( 140 __asm__ __volatile__(
106 "str %1, [%0]" 141 "str %1, [%0]"
107 : 142 :
108 : "r" (&rw->lock), "r" (0) 143 : "r" (&rw->lock), "r" (0)
109 : "cc", "memory"); 144 : "cc");
110} 145}
111 146
112/* 147/*
@@ -133,11 +168,17 @@ static inline void _raw_read_lock(rwlock_t *rw)
133" bmi 1b" 168" bmi 1b"
134 : "=&r" (tmp), "=&r" (tmp2) 169 : "=&r" (tmp), "=&r" (tmp2)
135 : "r" (&rw->lock) 170 : "r" (&rw->lock)
136 : "cc", "memory"); 171 : "cc");
172
173 smp_mb();
137} 174}
138 175
139static inline void _raw_read_unlock(rwlock_t *rw) 176static inline void _raw_read_unlock(rwlock_t *rw)
140{ 177{
178 unsigned long tmp, tmp2;
179
180 smp_mb();
181
141 __asm__ __volatile__( 182 __asm__ __volatile__(
142"1: ldrex %0, [%2]\n" 183"1: ldrex %0, [%2]\n"
143" sub %0, %0, #1\n" 184" sub %0, %0, #1\n"
@@ -146,24 +187,9 @@ static inline void _raw_read_unlock(rwlock_t *rw)
146" bne 1b" 187" bne 1b"
147 : "=&r" (tmp), "=&r" (tmp2) 188 : "=&r" (tmp), "=&r" (tmp2)
148 : "r" (&rw->lock) 189 : "r" (&rw->lock)
149 : "cc", "memory"); 190 : "cc");
150} 191}
151 192
152#define _raw_read_trylock(lock) generic_raw_read_trylock(lock) 193#define _raw_read_trylock(lock) generic_raw_read_trylock(lock)
153 194
154static inline int _raw_write_trylock(rwlock_t *rw)
155{
156 unsigned long tmp;
157
158 __asm__ __volatile__(
159"1: ldrex %0, [%1]\n"
160" teq %0, #0\n"
161" strexeq %0, %2, [%1]"
162 : "=&r" (tmp)
163 : "r" (&rw->lock), "r" (0x80000000)
164 : "cc", "memory");
165
166 return tmp == 0;
167}
168
169#endif /* __ASM_SPINLOCK_H */ 195#endif /* __ASM_SPINLOCK_H */
diff --git a/include/asm-arm/system.h b/include/asm-arm/system.h
index 2f44b2044214..8efa4ebdcacb 100644
--- a/include/asm-arm/system.h
+++ b/include/asm-arm/system.h
@@ -139,7 +139,12 @@ extern unsigned int user_debug;
139#define vectors_high() (0) 139#define vectors_high() (0)
140#endif 140#endif
141 141
142#if __LINUX_ARM_ARCH__ >= 6
143#define mb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" \
144 : : "r" (0) : "memory")
145#else
142#define mb() __asm__ __volatile__ ("" : : : "memory") 146#define mb() __asm__ __volatile__ ("" : : : "memory")
147#endif
143#define rmb() mb() 148#define rmb() mb()
144#define wmb() mb() 149#define wmb() mb()
145#define read_barrier_depends() do { } while(0) 150#define read_barrier_depends() do { } while(0)
@@ -323,12 +328,8 @@ do { \
323 * NOTE that this solution won't work on an SMP system, so explcitly 328 * NOTE that this solution won't work on an SMP system, so explcitly
324 * forbid it here. 329 * forbid it here.
325 */ 330 */
326#ifdef CONFIG_SMP
327#error SMP is not supported on SA1100/SA110
328#else
329#define swp_is_buggy 331#define swp_is_buggy
330#endif 332#endif
331#endif
332 333
333static inline unsigned long __xchg(unsigned long x, volatile void *ptr, int size) 334static inline unsigned long __xchg(unsigned long x, volatile void *ptr, int size)
334{ 335{
@@ -337,35 +338,68 @@ static inline unsigned long __xchg(unsigned long x, volatile void *ptr, int size
337#ifdef swp_is_buggy 338#ifdef swp_is_buggy
338 unsigned long flags; 339 unsigned long flags;
339#endif 340#endif
341#if __LINUX_ARM_ARCH__ >= 6
342 unsigned int tmp;
343#endif
340 344
341 switch (size) { 345 switch (size) {
342#ifdef swp_is_buggy 346#if __LINUX_ARM_ARCH__ >= 6
343 case 1: 347 case 1:
344 local_irq_save(flags); 348 asm volatile("@ __xchg1\n"
345 ret = *(volatile unsigned char *)ptr; 349 "1: ldrexb %0, [%3]\n"
346 *(volatile unsigned char *)ptr = x; 350 " strexb %1, %2, [%3]\n"
347 local_irq_restore(flags); 351 " teq %1, #0\n"
348 break; 352 " bne 1b"
349 353 : "=&r" (ret), "=&r" (tmp)
350 case 4: 354 : "r" (x), "r" (ptr)
351 local_irq_save(flags); 355 : "memory", "cc");
352 ret = *(volatile unsigned long *)ptr; 356 break;
353 *(volatile unsigned long *)ptr = x; 357 case 4:
354 local_irq_restore(flags); 358 asm volatile("@ __xchg4\n"
355 break; 359 "1: ldrex %0, [%3]\n"
360 " strex %1, %2, [%3]\n"
361 " teq %1, #0\n"
362 " bne 1b"
363 : "=&r" (ret), "=&r" (tmp)
364 : "r" (x), "r" (ptr)
365 : "memory", "cc");
366 break;
367#elif defined(swp_is_buggy)
368#ifdef CONFIG_SMP
369#error SMP is not supported on this platform
370#endif
371 case 1:
372 local_irq_save(flags);
373 ret = *(volatile unsigned char *)ptr;
374 *(volatile unsigned char *)ptr = x;
375 local_irq_restore(flags);
376 break;
377
378 case 4:
379 local_irq_save(flags);
380 ret = *(volatile unsigned long *)ptr;
381 *(volatile unsigned long *)ptr = x;
382 local_irq_restore(flags);
383 break;
356#else 384#else
357 case 1: __asm__ __volatile__ ("swpb %0, %1, [%2]" 385 case 1:
358 : "=&r" (ret) 386 asm volatile("@ __xchg1\n"
359 : "r" (x), "r" (ptr) 387 " swpb %0, %1, [%2]"
360 : "memory", "cc"); 388 : "=&r" (ret)
361 break; 389 : "r" (x), "r" (ptr)
362 case 4: __asm__ __volatile__ ("swp %0, %1, [%2]" 390 : "memory", "cc");
363 : "=&r" (ret) 391 break;
364 : "r" (x), "r" (ptr) 392 case 4:
365 : "memory", "cc"); 393 asm volatile("@ __xchg4\n"
366 break; 394 " swp %0, %1, [%2]"
395 : "=&r" (ret)
396 : "r" (x), "r" (ptr)
397 : "memory", "cc");
398 break;
367#endif 399#endif
368 default: __bad_xchg(ptr, size), ret = 0; 400 default:
401 __bad_xchg(ptr, size), ret = 0;
402 break;
369 } 403 }
370 404
371 return ret; 405 return ret;