2 * linux/include/asm-arm/proc-armo/locks.h
4 * Copyright (C) 2000 Russell King
5 * Fixes for 26 bit machines, (C) 2000 Dave Gilbert
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
11 * Interrupt safe locking assembler.
13 #ifndef __ASM_PROC_LOCKS_H
14 #define __ASM_PROC_LOCKS_H
16 /* Decrements by 1, fails if value < 0 */
17 #define __down_op(ptr,fail) \
19 __asm__ __volatile__ ( \
20 "@ atomic down operation\n" \
22 " orr lr, ip, #0x08000000\n" \
25 " and ip, ip, #0x0c000003\n" \
26 " subs lr, lr, #1\n" \
28 " orrmi ip, ip, #0x80000000 @ set N\n" \
34 : "ip", "lr", "cc"); \
37 #define __down_op_ret(ptr,fail) \
39 unsigned int result; \
40 __asm__ __volatile__ ( \
43 " orr lr, ip, #0x08000000\n" \
46 " and ip, ip, #0x0c000003\n" \
47 " subs lr, lr, #1\n" \
49 " orrmi ip, ip, #0x80000000 @ set N\n" \
57 : "ip", "lr", "cc"); \
61 #define __up_op(ptr,wake) \
63 __asm__ __volatile__ ( \
66 " orr lr, ip, #0x08000000\n" \
69 " and ip, ip, #0x0c000003\n" \
70 " adds lr, lr, #1\n" \
72 " orrle ip, ip, #0x80000000 @ set N - should this be mi ??? DAG ! \n" \
78 : "ip", "lr", "cc"); \
82 * The value 0x01000000 supports up to 128 processors and
83 * lots of processes. BIAS must be chosen such that sub'ing
84 * BIAS once per CPU will result in the long remaining
87 #define RW_LOCK_BIAS 0x01000000
88 #define RW_LOCK_BIAS_STR "0x01000000"
90 /* Decrements by RW_LOCK_BIAS rather than 1, fails if value != 0 */
91 #define __down_op_write(ptr,fail) \
93 __asm__ __volatile__( \
96 " orr lr, ip, #0x08000000\n" \
98 " and ip, ip, #0x0c000003\n" \
101 " subs lr, lr, %1\n" \
104 " orreq ip, ip, #0x40000000 @ set Z \n"\
109 : "r" (ptr), "I" (RW_LOCK_BIAS) \
110 : "ip", "lr", "cc"); \
113 /* Increments by RW_LOCK_BIAS, wakes if value >= 0 */
114 #define __up_op_write(ptr,wake) \
116 __asm__ __volatile__( \
119 " orr lr, ip, #0x08000000\n" \
123 " and ip, ip, #0x0c000003\n" \
124 " adds lr, lr, %1\n" \
127 " orrcs ip, ip, #0x20000000 @ set C\n" \
132 : "r" (ptr), "I" (RW_LOCK_BIAS) \
133 : "ip", "lr", "cc"); \
136 #define __down_op_read(ptr,fail) \
139 #define __up_op_read(ptr,wake) \
141 __asm__ __volatile__( \
144 " orr lr, ip, #0x08000000\n" \
148 " and ip, ip, #0x0c000003\n" \
149 " adds lr, lr, %1\n" \
152 " orreq ip, ip, #0x40000000 @ Set Z \n" \
157 : "r" (ptr), "I" (1) \
158 : "ip", "lr", "cc"); \