xref: /rk3399_rockchip-uboot/arch/arm/include/asm/atomic.h (revision 60bee396ec03ff5bfce10a0f0efd85e5a5783257)
1 /*
2  *  linux/include/asm-arm/atomic.h
3  *
4  *  Copyright (c) 1996 Russell King.
5  *
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.
9  *
10  *  Changelog:
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__
15  */
16 #ifndef __ASM_ARM_ATOMIC_H
17 #define __ASM_ARM_ATOMIC_H
18 
19 #ifndef CONFIG_ARCH_ROCKCHIP
20 #ifdef CONFIG_SMP
21 #error SMP not supported
22 #endif
23 #endif
24 
25 typedef struct { volatile int counter; } atomic_t;
26 #if BITS_PER_LONG == 32
27 typedef struct { volatile long long counter; } atomic64_t;
28 #else /* BIT_PER_LONG == 32 */
29 typedef struct { volatile long counter; } atomic64_t;
30 #endif
31 
32 #define ATOMIC_INIT(i)	{ (i) }
33 
34 #ifdef __KERNEL__
35 #include <asm/proc-armv/system.h>
36 
37 #define atomic_read(v)	((v)->counter)
38 #define atomic_set(v, i)	(((v)->counter) = (i))
39 #define atomic64_read(v)	atomic_read(v)
40 #define atomic64_set(v, i)	atomic_set(v, i)
41 
42 static inline void atomic_add(int i, volatile atomic_t *v)
43 {
44 	unsigned long flags = 0;
45 
46 	local_irq_save(flags);
47 	v->counter += i;
48 	local_irq_restore(flags);
49 }
50 
51 static inline void atomic_sub(int i, volatile atomic_t *v)
52 {
53 	unsigned long flags = 0;
54 
55 	local_irq_save(flags);
56 	v->counter -= i;
57 	local_irq_restore(flags);
58 }
59 
60 static inline void atomic_inc(volatile atomic_t *v)
61 {
62 	unsigned long flags = 0;
63 
64 	local_irq_save(flags);
65 	v->counter += 1;
66 	local_irq_restore(flags);
67 }
68 
69 static inline void atomic_dec(volatile atomic_t *v)
70 {
71 	unsigned long flags = 0;
72 
73 	local_irq_save(flags);
74 	v->counter -= 1;
75 	local_irq_restore(flags);
76 }
77 
78 static inline int atomic_dec_and_test(volatile atomic_t *v)
79 {
80 	unsigned long flags = 0;
81 	int val;
82 
83 	local_irq_save(flags);
84 	val = v->counter;
85 	v->counter = val -= 1;
86 	local_irq_restore(flags);
87 
88 	return val == 0;
89 }
90 
91 static inline int atomic_add_negative(int i, volatile atomic_t *v)
92 {
93 	unsigned long flags = 0;
94 	int val;
95 
96 	local_irq_save(flags);
97 	val = v->counter;
98 	v->counter = val += i;
99 	local_irq_restore(flags);
100 
101 	return val < 0;
102 }
103 
104 static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr)
105 {
106 	unsigned long flags = 0;
107 
108 	local_irq_save(flags);
109 	*addr &= ~mask;
110 	local_irq_restore(flags);
111 }
112 
113 #if BITS_PER_LONG == 32
114 
115 static inline void atomic64_add(long long i, volatile atomic64_t *v)
116 {
117 	unsigned long flags = 0;
118 
119 	local_irq_save(flags);
120 	v->counter += i;
121 	local_irq_restore(flags);
122 }
123 
124 static inline void atomic64_sub(long long i, volatile atomic64_t *v)
125 {
126 	unsigned long flags = 0;
127 
128 	local_irq_save(flags);
129 	v->counter -= i;
130 	local_irq_restore(flags);
131 }
132 
133 #else /* BIT_PER_LONG == 32 */
134 
135 static inline void atomic64_add(long i, volatile atomic64_t *v)
136 {
137 	unsigned long flags = 0;
138 
139 	local_irq_save(flags);
140 	v->counter += i;
141 	local_irq_restore(flags);
142 }
143 
144 static inline void atomic64_sub(long i, volatile atomic64_t *v)
145 {
146 	unsigned long flags = 0;
147 
148 	local_irq_save(flags);
149 	v->counter -= i;
150 	local_irq_restore(flags);
151 }
152 #endif
153 
154 static inline void atomic64_inc(volatile atomic64_t *v)
155 {
156 	unsigned long flags = 0;
157 
158 	local_irq_save(flags);
159 	v->counter += 1;
160 	local_irq_restore(flags);
161 }
162 
163 static inline void atomic64_dec(volatile atomic64_t *v)
164 {
165 	unsigned long flags = 0;
166 
167 	local_irq_save(flags);
168 	v->counter -= 1;
169 	local_irq_restore(flags);
170 }
171 
172 /* Atomic operations are already serializing on ARM */
173 #define smp_mb__before_atomic_dec()	barrier()
174 #define smp_mb__after_atomic_dec()	barrier()
175 #define smp_mb__before_atomic_inc()	barrier()
176 #define smp_mb__after_atomic_inc()	barrier()
177 
178 #endif
179 #endif
180