2 * Copyright (C) 2006 Atmark Techno, Inc.
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
9 #ifndef _ASM_MICROBLAZE_ATOMIC_H
10 #define _ASM_MICROBLAZE_ATOMIC_H
12 #include <linux/types.h>
13 #include <linux/compiler.h> /* likely */
14 #include <asm/system.h> /* local_irq_XXX and friends */
16 #define ATOMIC_INIT(i) { (i) }
17 #define atomic_read(v) ((v)->counter)
18 #define atomic_set(v, i) (((v)->counter) = (i))
20 #define atomic_inc(v) (atomic_add_return(1, (v)))
21 #define atomic_dec(v) (atomic_sub_return(1, (v)))
23 #define atomic_add(i, v) (atomic_add_return(i, (v)))
24 #define atomic_sub(i, v) (atomic_sub_return(i, (v)))
26 #define atomic_inc_return(v) (atomic_add_return(1, (v)))
27 #define atomic_dec_return(v) (atomic_sub_return(1, (v)))
29 #define atomic_inc_and_test(v) (atomic_add_return(1, (v)) == 0)
30 #define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0)
32 #define atomic_inc_not_zero(v) (atomic_add_unless((v), 1, 0))
34 #define atomic_sub_and_test(i, v) (atomic_sub_return((i), (v)) == 0)
36 static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
41 local_irq_save(flags);
43 if (likely(ret == old))
45 local_irq_restore(flags);
50 static inline int atomic_add_unless(atomic_t *v, int a, int u)
55 while (c != u && (old = atomic_cmpxchg((v), c, c + a)) != c)
60 static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr)
64 local_irq_save(flags);
66 local_irq_restore(flags);
70 * atomic_add_return - add and return
71 * @i: integer value to add
72 * @v: pointer of type atomic_t
74 * Atomically adds @i to @v and returns @i + @v
76 static inline int atomic_add_return(int i, atomic_t *v)
81 local_irq_save(flags);
83 v->counter = val += i;
84 local_irq_restore(flags);
89 static inline int atomic_sub_return(int i, atomic_t *v)
91 return atomic_add_return(-i, v);
95 * Atomically test *v and decrement if it is greater than 0.
96 * The function returns the old value of *v minus 1.
98 static inline int atomic_dec_if_positive(atomic_t *v)
103 local_irq_save(flags);
104 res = v->counter - 1;
107 local_irq_restore(flags);
112 #define atomic_add_negative(a, v) (atomic_add_return((a), (v)) < 0)
113 #define atomic_xchg(v, new) (xchg(&((v)->counter), new))
115 /* Atomic operations are already serializing */
116 #define smp_mb__before_atomic_dec() barrier()
117 #define smp_mb__after_atomic_dec() barrier()
118 #define smp_mb__before_atomic_inc() barrier()
119 #define smp_mb__after_atomic_inc() barrier()
121 #include <asm-generic/atomic-long.h>
123 #endif /* _ASM_MICROBLAZE_ATOMIC_H */