2 * linux/include/asm-arm/atomic.h
4 * Copyright (c) 1996 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.
11 * 27-06-1996 RMK Created
12 * 13-04-1997 RMK Made functions atomic!
13 * 07-12-1997 RMK Upgraded for v2.1.
14 * 26-08-1998 PJB Added #ifdef __KERNEL__
16 #ifndef __ASM_ARM_ATOMIC_H
17 #define __ASM_ARM_ATOMIC_H
20 #error SMP not supported
23 typedef struct { volatile int counter; } atomic_t;
24 #if BITS_PER_LONG == 32
25 typedef struct { volatile long long counter; } atomic64_t;
26 #else /* BIT_PER_LONG == 32 */
27 typedef struct { volatile long counter; } atomic64_t;
30 #define ATOMIC_INIT(i) { (i) }
33 #include <asm/proc-armv/system.h>
35 #define atomic_read(v) ((v)->counter)
36 #define atomic_set(v, i) (((v)->counter) = (i))
37 #define atomic64_read(v) atomic_read(v)
38 #define atomic64_set(v, i) atomic_set(v, i)
40 static inline void atomic_add(int i, volatile atomic_t *v)
42 unsigned long flags = 0;
44 local_irq_save(flags);
46 local_irq_restore(flags);
49 static inline void atomic_sub(int i, volatile atomic_t *v)
51 unsigned long flags = 0;
53 local_irq_save(flags);
55 local_irq_restore(flags);
58 static inline void atomic_inc(volatile atomic_t *v)
60 unsigned long flags = 0;
62 local_irq_save(flags);
64 local_irq_restore(flags);
67 static inline void atomic_dec(volatile atomic_t *v)
69 unsigned long flags = 0;
71 local_irq_save(flags);
73 local_irq_restore(flags);
76 static inline int atomic_dec_and_test(volatile atomic_t *v)
78 unsigned long flags = 0;
81 local_irq_save(flags);
83 v->counter = val -= 1;
84 local_irq_restore(flags);
89 static inline int atomic_add_negative(int i, volatile atomic_t *v)
91 unsigned long flags = 0;
94 local_irq_save(flags);
96 v->counter = val += i;
97 local_irq_restore(flags);
102 static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr)
104 unsigned long flags = 0;
106 local_irq_save(flags);
108 local_irq_restore(flags);
111 #if BITS_PER_LONG == 32
113 static inline void atomic64_add(long long i, volatile atomic64_t *v)
115 unsigned long flags = 0;
117 local_irq_save(flags);
119 local_irq_restore(flags);
122 static inline void atomic64_sub(long long i, volatile atomic64_t *v)
124 unsigned long flags = 0;
126 local_irq_save(flags);
128 local_irq_restore(flags);
131 #else /* BIT_PER_LONG == 32 */
133 static inline void atomic64_add(long i, volatile atomic64_t *v)
135 unsigned long flags = 0;
137 local_irq_save(flags);
139 local_irq_restore(flags);
142 static inline void atomic64_sub(long i, volatile atomic64_t *v)
144 unsigned long flags = 0;
146 local_irq_save(flags);
148 local_irq_restore(flags);
152 static inline void atomic64_inc(volatile atomic64_t *v)
154 unsigned long flags = 0;
156 local_irq_save(flags);
158 local_irq_restore(flags);
161 static inline void atomic64_dec(volatile atomic64_t *v)
163 unsigned long flags = 0;
165 local_irq_save(flags);
167 local_irq_restore(flags);
170 /* Atomic operations are already serializing on ARM */
171 #define smp_mb__before_atomic_dec() barrier()
172 #define smp_mb__after_atomic_dec() barrier()
173 #define smp_mb__before_atomic_inc() barrier()
174 #define smp_mb__after_atomic_inc() barrier()