2 * arch/arm/include/asm/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"); \
35 #define __down_op_ret(ptr,fail) \
38 __asm__ __volatile__( \
40 "1: ldrex lr, [%1]\n" \
42 " strex ip, lr, [%1]\n" \
51 : "r" (ptr), "I" (1) \
52 : "ip", "lr", "cc"); \
57 #define __up_op(ptr,wake) \
60 __asm__ __volatile__( \
62 "1: ldrex lr, [%0]\n" \
64 " strex ip, lr, [%0]\n" \
71 : "r" (ptr), "I" (1) \
72 : "ip", "lr", "cc"); \
76 * The value 0x01000000 supports up to 128 processors and
77 * lots of processes. BIAS must be chosen such that sub'ing
78 * BIAS once per CPU will result in the long remaining
81 #define RW_LOCK_BIAS 0x01000000
82 #define RW_LOCK_BIAS_STR "0x01000000"
84 #define __down_op_write(ptr,fail) \
86 __asm__ __volatile__( \
88 "1: ldrex lr, [%0]\n" \
90 " strex ip, lr, [%0]\n" \
97 : "r" (ptr), "I" (RW_LOCK_BIAS) \
98 : "ip", "lr", "cc"); \
102 #define __up_op_write(ptr,wake) \
105 __asm__ __volatile__( \
107 "1: ldrex lr, [%0]\n" \
108 " adds lr, lr, %1\n" \
109 " strex ip, lr, [%0]\n" \
115 : "r" (ptr), "I" (RW_LOCK_BIAS) \
116 : "ip", "lr", "cc"); \
119 #define __down_op_read(ptr,fail) \
122 #define __up_op_read(ptr,wake) \
125 __asm__ __volatile__( \
127 "1: ldrex lr, [%0]\n" \
128 " add lr, lr, %1\n" \
129 " strex ip, lr, [%0]\n" \
136 : "r" (ptr), "I" (1) \
137 : "ip", "lr", "cc"); \
142 #define __down_op(ptr,fail) \
144 __asm__ __volatile__( \
147 " orr lr, ip, #128\n" \
148 " msr cpsr_c, lr\n" \
150 " subs lr, lr, %1\n" \
152 " msr cpsr_c, ip\n" \
156 : "r" (ptr), "I" (1) \
157 : "ip", "lr", "cc"); \
161 #define __down_op_ret(ptr,fail) \
164 __asm__ __volatile__( \
167 " orr lr, ip, #128\n" \
168 " msr cpsr_c, lr\n" \
170 " subs lr, lr, %2\n" \
172 " msr cpsr_c, ip\n" \
175 " blmi " #fail "\n" \
178 : "r" (ptr), "I" (1) \
179 : "ip", "lr", "cc"); \
184 #define __up_op(ptr,wake) \
187 __asm__ __volatile__( \
190 " orr lr, ip, #128\n" \
191 " msr cpsr_c, lr\n" \
193 " adds lr, lr, %1\n" \
195 " msr cpsr_c, ip\n" \
199 : "r" (ptr), "I" (1) \
200 : "ip", "lr", "cc"); \
204 * The value 0x01000000 supports up to 128 processors and
205 * lots of processes. BIAS must be chosen such that sub'ing
206 * BIAS once per CPU will result in the long remaining
209 #define RW_LOCK_BIAS 0x01000000
210 #define RW_LOCK_BIAS_STR "0x01000000"
212 #define __down_op_write(ptr,fail) \
214 __asm__ __volatile__( \
215 "@ down_op_write\n" \
217 " orr lr, ip, #128\n" \
218 " msr cpsr_c, lr\n" \
220 " subs lr, lr, %1\n" \
222 " msr cpsr_c, ip\n" \
226 : "r" (ptr), "I" (RW_LOCK_BIAS) \
227 : "ip", "lr", "cc"); \
231 #define __up_op_write(ptr,wake) \
233 __asm__ __volatile__( \
236 " orr lr, ip, #128\n" \
237 " msr cpsr_c, lr\n" \
239 " adds lr, lr, %1\n" \
241 " msr cpsr_c, ip\n" \
245 : "r" (ptr), "I" (RW_LOCK_BIAS) \
246 : "ip", "lr", "cc"); \
250 #define __down_op_read(ptr,fail) \
253 #define __up_op_read(ptr,wake) \
256 __asm__ __volatile__( \
259 " orr lr, ip, #128\n" \
260 " msr cpsr_c, lr\n" \
262 " adds lr, lr, %1\n" \
264 " msr cpsr_c, ip\n" \
268 : "r" (ptr), "I" (1) \
269 : "ip", "lr", "cc"); \