aboutsummaryrefslogtreecommitdiffstats
path: root/include/asm-generic/atomic.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/asm-generic/atomic.h')
-rw-r--r--include/asm-generic/atomic.h22
1 files changed, 9 insertions, 13 deletions
diff --git a/include/asm-generic/atomic.h b/include/asm-generic/atomic.h
index c99c64dc5f3d..e53347fbf1da 100644
--- a/include/asm-generic/atomic.h
+++ b/include/asm-generic/atomic.h
@@ -30,18 +30,16 @@
30 * atomic_read - read atomic variable 30 * atomic_read - read atomic variable
31 * @v: pointer of type atomic_t 31 * @v: pointer of type atomic_t
32 * 32 *
33 * Atomically reads the value of @v. Note that the guaranteed 33 * Atomically reads the value of @v.
34 * useful range of an atomic_t is only 24 bits.
35 */ 34 */
36#define atomic_read(v) ((v)->counter) 35#define atomic_read(v) (*(volatile int *)&(v)->counter)
37 36
38/** 37/**
39 * atomic_set - set atomic variable 38 * atomic_set - set atomic variable
40 * @v: pointer of type atomic_t 39 * @v: pointer of type atomic_t
41 * @i: required value 40 * @i: required value
42 * 41 *
43 * Atomically sets the value of @v to @i. Note that the guaranteed 42 * Atomically sets the value of @v to @i.
44 * useful range of an atomic_t is only 24 bits.
45 */ 43 */
46#define atomic_set(v, i) (((v)->counter) = (i)) 44#define atomic_set(v, i) (((v)->counter) = (i))
47 45
@@ -53,18 +51,17 @@
53 * @v: pointer of type atomic_t 51 * @v: pointer of type atomic_t
54 * 52 *
55 * Atomically adds @i to @v and returns the result 53 * Atomically adds @i to @v and returns the result
56 * Note that the guaranteed useful range of an atomic_t is only 24 bits.
57 */ 54 */
58static inline int atomic_add_return(int i, atomic_t *v) 55static inline int atomic_add_return(int i, atomic_t *v)
59{ 56{
60 unsigned long flags; 57 unsigned long flags;
61 int temp; 58 int temp;
62 59
63 local_irq_save(flags); 60 raw_local_irq_save(flags); /* Don't trace it in a irqsoff handler */
64 temp = v->counter; 61 temp = v->counter;
65 temp += i; 62 temp += i;
66 v->counter = temp; 63 v->counter = temp;
67 local_irq_restore(flags); 64 raw_local_irq_restore(flags);
68 65
69 return temp; 66 return temp;
70} 67}
@@ -75,18 +72,17 @@ static inline int atomic_add_return(int i, atomic_t *v)
75 * @v: pointer of type atomic_t 72 * @v: pointer of type atomic_t
76 * 73 *
77 * Atomically subtracts @i from @v and returns the result 74 * Atomically subtracts @i from @v and returns the result
78 * Note that the guaranteed useful range of an atomic_t is only 24 bits.
79 */ 75 */
80static inline int atomic_sub_return(int i, atomic_t *v) 76static inline int atomic_sub_return(int i, atomic_t *v)
81{ 77{
82 unsigned long flags; 78 unsigned long flags;
83 int temp; 79 int temp;
84 80
85 local_irq_save(flags); 81 raw_local_irq_save(flags); /* Don't trace it in a irqsoff handler */
86 temp = v->counter; 82 temp = v->counter;
87 temp -= i; 83 temp -= i;
88 v->counter = temp; 84 v->counter = temp;
89 local_irq_restore(flags); 85 raw_local_irq_restore(flags);
90 86
91 return temp; 87 return temp;
92} 88}
@@ -139,9 +135,9 @@ static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr)
139 unsigned long flags; 135 unsigned long flags;
140 136
141 mask = ~mask; 137 mask = ~mask;
142 local_irq_save(flags); 138 raw_local_irq_save(flags); /* Don't trace it in a irqsoff handler */
143 *addr &= mask; 139 *addr &= mask;
144 local_irq_restore(flags); 140 raw_local_irq_restore(flags);
145} 141}
146 142
147#define atomic_xchg(ptr, v) (xchg(&(ptr)->counter, (v))) 143#define atomic_xchg(ptr, v) (xchg(&(ptr)->counter, (v)))