blob: 94d0747194af54d333e096a12ed8e271620fec11 [file] [log] [blame]
Chris Packhamf1b96f42018-09-08 21:39:04 +12001/* SPDX-License-Identifier: GPL-2.0+ */
2
3#ifndef _ASM_GENERIC_ATOMIC_H
4#define _ASM_GENERIC_ATOMIC_H
5
6typedef struct { volatile int counter; } atomic_t;
7#if BITS_PER_LONG == 32
8typedef struct { volatile long long counter; } atomic64_t;
9#else /* BIT_PER_LONG == 32 */
10typedef struct { volatile long counter; } atomic64_t;
11#endif
12
13#define ATOMIC_INIT(i) { (i) }
14
15#define atomic_read(v) ((v)->counter)
16#define atomic_set(v, i) ((v)->counter = (i))
17#define atomic64_read(v) atomic_read(v)
18#define atomic64_set(v, i) atomic_set(v, i)
19
20static inline void atomic_add(int i, atomic_t *v)
21{
22 unsigned long flags = 0;
23
24 local_irq_save(flags);
25 v->counter += i;
26 local_irq_restore(flags);
27}
28
29static inline void atomic_sub(int i, atomic_t *v)
30{
31 unsigned long flags = 0;
32
33 local_irq_save(flags);
34 v->counter -= i;
35 local_irq_restore(flags);
36}
37
38static inline void atomic_inc(atomic_t *v)
39{
40 unsigned long flags = 0;
41
42 local_irq_save(flags);
43 ++v->counter;
44 local_irq_restore(flags);
45}
46
47static inline void atomic_dec(atomic_t *v)
48{
49 unsigned long flags = 0;
50
51 local_irq_save(flags);
52 --v->counter;
53 local_irq_restore(flags);
54}
55
56static inline int atomic_dec_and_test(volatile atomic_t *v)
57{
58 unsigned long flags = 0;
59 int val;
60
61 local_irq_save(flags);
62 val = v->counter;
63 v->counter = val -= 1;
64 local_irq_restore(flags);
65
66 return val == 0;
67}
68
69static inline int atomic_add_negative(int i, volatile atomic_t *v)
70{
71 unsigned long flags = 0;
72 int val;
73
74 local_irq_save(flags);
75 val = v->counter;
76 v->counter = val += i;
77 local_irq_restore(flags);
78
79 return val < 0;
80}
81
82static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr)
83{
84 unsigned long flags = 0;
85
86 local_irq_save(flags);
87 *addr &= ~mask;
88 local_irq_restore(flags);
89}
90
91#if BITS_PER_LONG == 32
92
93static inline void atomic64_add(long long i, volatile atomic64_t *v)
94{
95 unsigned long flags = 0;
96
97 local_irq_save(flags);
98 v->counter += i;
99 local_irq_restore(flags);
100}
101
102static inline void atomic64_sub(long long i, volatile atomic64_t *v)
103{
104 unsigned long flags = 0;
105
106 local_irq_save(flags);
107 v->counter -= i;
108 local_irq_restore(flags);
109}
110
111#else /* BIT_PER_LONG == 32 */
112
113static inline void atomic64_add(long i, volatile atomic64_t *v)
114{
115 unsigned long flags = 0;
116
117 local_irq_save(flags);
118 v->counter += i;
119 local_irq_restore(flags);
120}
121
122static inline void atomic64_sub(long i, volatile atomic64_t *v)
123{
124 unsigned long flags = 0;
125
126 local_irq_save(flags);
127 v->counter -= i;
128 local_irq_restore(flags);
129}
130#endif
131
132static inline void atomic64_inc(volatile atomic64_t *v)
133{
134 unsigned long flags = 0;
135
136 local_irq_save(flags);
137 v->counter += 1;
138 local_irq_restore(flags);
139}
140
141static inline void atomic64_dec(volatile atomic64_t *v)
142{
143 unsigned long flags = 0;
144
145 local_irq_save(flags);
146 v->counter -= 1;
147 local_irq_restore(flags);
148}
149
150#endif