2 * linux/include/asm-arm/locks.h
4 * Copyright (C) 2000 Russell King
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.
10 * Interrupt safe locking assembler.
12 #ifndef __ASM_PROC_LOCKS_H
13 #define __ASM_PROC_LOCKS_H
15 #if __LINUX_ARM_ARCH__ >= 6
17 #define __down_op(ptr,fail) \
19 __asm__ __volatile__( \
21 "1: ldrex lr, [%0]\n" \
23 " strex ip, lr, [%0]\n" \
30 : "r" (ptr), "I" (1) \
31 : "ip", "lr", "cc", "memory"); \
34 #define __down_op_ret(ptr,fail) \
37 __asm__ __volatile__( \
39 "1: ldrex lr, [%1]\n" \
41 " strex ip, lr, [%1]\n" \
50 : "r" (ptr), "I" (1) \
51 : "ip", "lr", "cc", "memory"); \
55 #define __up_op(ptr,wake) \
57 __asm__ __volatile__( \
59 "1: ldrex lr, [%0]\n" \
61 " strex ip, lr, [%0]\n" \
68 : "r" (ptr), "I" (1) \
69 : "ip", "lr", "cc", "memory"); \
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
78 #define RW_LOCK_BIAS 0x01000000
79 #define RW_LOCK_BIAS_STR "0x01000000"
81 #define __down_op_write(ptr,fail) \
83 __asm__ __volatile__( \
85 "1: ldrex lr, [%0]\n" \
87 " strex ip, lr, [%0]\n" \
94 : "r" (ptr), "I" (RW_LOCK_BIAS) \
95 : "ip", "lr", "cc", "memory"); \
98 #define __up_op_write(ptr,wake) \
100 __asm__ __volatile__( \
102 "1: ldrex lr, [%0]\n" \
103 " add lr, lr, %1\n" \
104 " strex ip, lr, [%0]\n" \
110 : "r" (ptr), "I" (RW_LOCK_BIAS) \
111 : "ip", "lr", "cc", "memory"); \
114 #define __down_op_read(ptr,fail) \
117 #define __up_op_read(ptr,wake) \
119 __asm__ __volatile__( \
121 "1: ldrex lr, [%0]\n" \
122 " add lr, lr, %1\n" \
123 " strex ip, lr, [%0]\n" \
130 : "r" (ptr), "I" (1) \
131 : "ip", "lr", "cc", "memory"); \
136 #define __down_op(ptr,fail) \
138 __asm__ __volatile__( \
141 " orr lr, ip, #128\n" \
142 " msr cpsr_c, lr\n" \
144 " subs lr, lr, %1\n" \
146 " msr cpsr_c, ip\n" \
150 : "r" (ptr), "I" (1) \
151 : "ip", "lr", "cc", "memory"); \
154 #define __down_op_ret(ptr,fail) \
157 __asm__ __volatile__( \
160 " orr lr, ip, #128\n" \
161 " msr cpsr_c, lr\n" \
163 " subs lr, lr, %2\n" \
165 " msr cpsr_c, ip\n" \
168 " blmi " #fail "\n" \
171 : "r" (ptr), "I" (1) \
172 : "ip", "lr", "cc", "memory"); \
176 #define __up_op(ptr,wake) \
178 __asm__ __volatile__( \
181 " orr lr, ip, #128\n" \
182 " msr cpsr_c, lr\n" \
184 " adds lr, lr, %1\n" \
186 " msr cpsr_c, ip\n" \
190 : "r" (ptr), "I" (1) \
191 : "ip", "lr", "cc", "memory"); \
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
200 #define RW_LOCK_BIAS 0x01000000
201 #define RW_LOCK_BIAS_STR "0x01000000"
203 #define __down_op_write(ptr,fail) \
205 __asm__ __volatile__( \
206 "@ down_op_write\n" \
208 " orr lr, ip, #128\n" \
209 " msr cpsr_c, lr\n" \
211 " subs lr, lr, %1\n" \
213 " msr cpsr_c, ip\n" \
217 : "r" (ptr), "I" (RW_LOCK_BIAS) \
218 : "ip", "lr", "cc", "memory"); \
221 #define __up_op_write(ptr,wake) \
223 __asm__ __volatile__( \
226 " orr lr, ip, #128\n" \
227 " msr cpsr_c, lr\n" \
229 " adds lr, lr, %1\n" \
231 " msr cpsr_c, ip\n" \
235 : "r" (ptr), "I" (RW_LOCK_BIAS) \
236 : "ip", "lr", "cc", "memory"); \
239 #define __down_op_read(ptr,fail) \
242 #define __up_op_read(ptr,wake) \
244 __asm__ __volatile__( \
247 " orr lr, ip, #128\n" \
248 " msr cpsr_c, lr\n" \
250 " adds lr, lr, %1\n" \
252 " msr cpsr_c, ip\n" \
256 : "r" (ptr), "I" (1) \
257 : "ip", "lr", "cc", "memory"); \