]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blob - include/asm-arm/locks.h
Linux-2.6.12-rc2
[mirror_ubuntu-artful-kernel.git] / include / asm-arm / locks.h
1 /*
2 * linux/include/asm-arm/locks.h
3 *
4 * Copyright (C) 2000 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * Interrupt safe locking assembler.
11 */
12 #ifndef __ASM_PROC_LOCKS_H
13 #define __ASM_PROC_LOCKS_H
14
15 #if __LINUX_ARM_ARCH__ >= 6
16
17 #define __down_op(ptr,fail) \
18 ({ \
19 __asm__ __volatile__( \
20 "@ down_op\n" \
21 "1: ldrex lr, [%0]\n" \
22 " sub lr, lr, %1\n" \
23 " strex ip, lr, [%0]\n" \
24 " teq ip, #0\n" \
25 " bne 1b\n" \
26 " teq lr, #0\n" \
27 " movmi ip, %0\n" \
28 " blmi " #fail \
29 : \
30 : "r" (ptr), "I" (1) \
31 : "ip", "lr", "cc", "memory"); \
32 })
33
34 #define __down_op_ret(ptr,fail) \
35 ({ \
36 unsigned int ret; \
37 __asm__ __volatile__( \
38 "@ down_op_ret\n" \
39 "1: ldrex lr, [%1]\n" \
40 " sub lr, lr, %2\n" \
41 " strex ip, lr, [%1]\n" \
42 " teq ip, #0\n" \
43 " bne 1b\n" \
44 " teq lr, #0\n" \
45 " movmi ip, %1\n" \
46 " movpl ip, #0\n" \
47 " blmi " #fail "\n" \
48 " mov %0, ip" \
49 : "=&r" (ret) \
50 : "r" (ptr), "I" (1) \
51 : "ip", "lr", "cc", "memory"); \
52 ret; \
53 })
54
55 #define __up_op(ptr,wake) \
56 ({ \
57 __asm__ __volatile__( \
58 "@ up_op\n" \
59 "1: ldrex lr, [%0]\n" \
60 " add lr, lr, %1\n" \
61 " strex ip, lr, [%0]\n" \
62 " teq ip, #0\n" \
63 " bne 1b\n" \
64 " teq lr, #0\n" \
65 " movle ip, %0\n" \
66 " blle " #wake \
67 : \
68 : "r" (ptr), "I" (1) \
69 : "ip", "lr", "cc", "memory"); \
70 })
71
72 /*
73 * The value 0x01000000 supports up to 128 processors and
74 * lots of processes. BIAS must be chosen such that sub'ing
75 * BIAS once per CPU will result in the long remaining
76 * negative.
77 */
78 #define RW_LOCK_BIAS 0x01000000
79 #define RW_LOCK_BIAS_STR "0x01000000"
80
81 #define __down_op_write(ptr,fail) \
82 ({ \
83 __asm__ __volatile__( \
84 "@ down_op_write\n" \
85 "1: ldrex lr, [%0]\n" \
86 " sub lr, lr, %1\n" \
87 " strex ip, lr, [%0]\n" \
88 " teq ip, #0\n" \
89 " bne 1b\n" \
90 " teq lr, #0\n" \
91 " movne ip, %0\n" \
92 " blne " #fail \
93 : \
94 : "r" (ptr), "I" (RW_LOCK_BIAS) \
95 : "ip", "lr", "cc", "memory"); \
96 })
97
98 #define __up_op_write(ptr,wake) \
99 ({ \
100 __asm__ __volatile__( \
101 "@ up_op_read\n" \
102 "1: ldrex lr, [%0]\n" \
103 " add lr, lr, %1\n" \
104 " strex ip, lr, [%0]\n" \
105 " teq ip, #0\n" \
106 " bne 1b\n" \
107 " movcs ip, %0\n" \
108 " blcs " #wake \
109 : \
110 : "r" (ptr), "I" (RW_LOCK_BIAS) \
111 : "ip", "lr", "cc", "memory"); \
112 })
113
114 #define __down_op_read(ptr,fail) \
115 __down_op(ptr, fail)
116
117 #define __up_op_read(ptr,wake) \
118 ({ \
119 __asm__ __volatile__( \
120 "@ up_op_read\n" \
121 "1: ldrex lr, [%0]\n" \
122 " add lr, lr, %1\n" \
123 " strex ip, lr, [%0]\n" \
124 " teq ip, #0\n" \
125 " bne 1b\n" \
126 " teq lr, #0\n" \
127 " moveq ip, %0\n" \
128 " bleq " #wake \
129 : \
130 : "r" (ptr), "I" (1) \
131 : "ip", "lr", "cc", "memory"); \
132 })
133
134 #else
135
136 #define __down_op(ptr,fail) \
137 ({ \
138 __asm__ __volatile__( \
139 "@ down_op\n" \
140 " mrs ip, cpsr\n" \
141 " orr lr, ip, #128\n" \
142 " msr cpsr_c, lr\n" \
143 " ldr lr, [%0]\n" \
144 " subs lr, lr, %1\n" \
145 " str lr, [%0]\n" \
146 " msr cpsr_c, ip\n" \
147 " movmi ip, %0\n" \
148 " blmi " #fail \
149 : \
150 : "r" (ptr), "I" (1) \
151 : "ip", "lr", "cc", "memory"); \
152 })
153
154 #define __down_op_ret(ptr,fail) \
155 ({ \
156 unsigned int ret; \
157 __asm__ __volatile__( \
158 "@ down_op_ret\n" \
159 " mrs ip, cpsr\n" \
160 " orr lr, ip, #128\n" \
161 " msr cpsr_c, lr\n" \
162 " ldr lr, [%1]\n" \
163 " subs lr, lr, %2\n" \
164 " str lr, [%1]\n" \
165 " msr cpsr_c, ip\n" \
166 " movmi ip, %1\n" \
167 " movpl ip, #0\n" \
168 " blmi " #fail "\n" \
169 " mov %0, ip" \
170 : "=&r" (ret) \
171 : "r" (ptr), "I" (1) \
172 : "ip", "lr", "cc", "memory"); \
173 ret; \
174 })
175
176 #define __up_op(ptr,wake) \
177 ({ \
178 __asm__ __volatile__( \
179 "@ up_op\n" \
180 " mrs ip, cpsr\n" \
181 " orr lr, ip, #128\n" \
182 " msr cpsr_c, lr\n" \
183 " ldr lr, [%0]\n" \
184 " adds lr, lr, %1\n" \
185 " str lr, [%0]\n" \
186 " msr cpsr_c, ip\n" \
187 " movle ip, %0\n" \
188 " blle " #wake \
189 : \
190 : "r" (ptr), "I" (1) \
191 : "ip", "lr", "cc", "memory"); \
192 })
193
194 /*
195 * The value 0x01000000 supports up to 128 processors and
196 * lots of processes. BIAS must be chosen such that sub'ing
197 * BIAS once per CPU will result in the long remaining
198 * negative.
199 */
200 #define RW_LOCK_BIAS 0x01000000
201 #define RW_LOCK_BIAS_STR "0x01000000"
202
203 #define __down_op_write(ptr,fail) \
204 ({ \
205 __asm__ __volatile__( \
206 "@ down_op_write\n" \
207 " mrs ip, cpsr\n" \
208 " orr lr, ip, #128\n" \
209 " msr cpsr_c, lr\n" \
210 " ldr lr, [%0]\n" \
211 " subs lr, lr, %1\n" \
212 " str lr, [%0]\n" \
213 " msr cpsr_c, ip\n" \
214 " movne ip, %0\n" \
215 " blne " #fail \
216 : \
217 : "r" (ptr), "I" (RW_LOCK_BIAS) \
218 : "ip", "lr", "cc", "memory"); \
219 })
220
221 #define __up_op_write(ptr,wake) \
222 ({ \
223 __asm__ __volatile__( \
224 "@ up_op_read\n" \
225 " mrs ip, cpsr\n" \
226 " orr lr, ip, #128\n" \
227 " msr cpsr_c, lr\n" \
228 " ldr lr, [%0]\n" \
229 " adds lr, lr, %1\n" \
230 " str lr, [%0]\n" \
231 " msr cpsr_c, ip\n" \
232 " movcs ip, %0\n" \
233 " blcs " #wake \
234 : \
235 : "r" (ptr), "I" (RW_LOCK_BIAS) \
236 : "ip", "lr", "cc", "memory"); \
237 })
238
239 #define __down_op_read(ptr,fail) \
240 __down_op(ptr, fail)
241
242 #define __up_op_read(ptr,wake) \
243 ({ \
244 __asm__ __volatile__( \
245 "@ up_op_read\n" \
246 " mrs ip, cpsr\n" \
247 " orr lr, ip, #128\n" \
248 " msr cpsr_c, lr\n" \
249 " ldr lr, [%0]\n" \
250 " adds lr, lr, %1\n" \
251 " str lr, [%0]\n" \
252 " msr cpsr_c, ip\n" \
253 " moveq ip, %0\n" \
254 " bleq " #wake \
255 : \
256 : "r" (ptr), "I" (1) \
257 : "ip", "lr", "cc", "memory"); \
258 })
259
260 #endif
261
262 #endif