xref: /rk3399_rockchip-uboot/arch/arm/include/asm/atomic.h (revision 2f96fde52db8dd705f6c1efc8530684405024993)
1819833afSPeter Tyser /*
2819833afSPeter Tyser  *  linux/include/asm-arm/atomic.h
3819833afSPeter Tyser  *
4819833afSPeter Tyser  *  Copyright (c) 1996 Russell King.
5819833afSPeter Tyser  *
6819833afSPeter Tyser  * This program is free software; you can redistribute it and/or modify
7819833afSPeter Tyser  * it under the terms of the GNU General Public License version 2 as
8819833afSPeter Tyser  * published by the Free Software Foundation.
9819833afSPeter Tyser  *
10819833afSPeter Tyser  *  Changelog:
11819833afSPeter Tyser  *   27-06-1996	RMK	Created
12819833afSPeter Tyser  *   13-04-1997	RMK	Made functions atomic!
13819833afSPeter Tyser  *   07-12-1997	RMK	Upgraded for v2.1.
14819833afSPeter Tyser  *   26-08-1998	PJB	Added #ifdef __KERNEL__
15819833afSPeter Tyser  */
16819833afSPeter Tyser #ifndef __ASM_ARM_ATOMIC_H
17819833afSPeter Tyser #define __ASM_ARM_ATOMIC_H
18819833afSPeter Tyser 
19*2f96fde5SJoseph Chen #ifndef CONFIG_ARCH_ROCKCHIP
20819833afSPeter Tyser #ifdef CONFIG_SMP
21819833afSPeter Tyser #error SMP not supported
22819833afSPeter Tyser #endif
23*2f96fde5SJoseph Chen #endif
24819833afSPeter Tyser 
25819833afSPeter Tyser typedef struct { volatile int counter; } atomic_t;
2659a51a10SAdam Oleksy #if BITS_PER_LONG == 32
2759a51a10SAdam Oleksy typedef struct { volatile long long counter; } atomic64_t;
2859a51a10SAdam Oleksy #else /* BIT_PER_LONG == 32 */
2959a51a10SAdam Oleksy typedef struct { volatile long counter; } atomic64_t;
3059a51a10SAdam Oleksy #endif
31819833afSPeter Tyser 
32819833afSPeter Tyser #define ATOMIC_INIT(i)	{ (i) }
33819833afSPeter Tyser 
34819833afSPeter Tyser #ifdef __KERNEL__
357d89982bSVasili Galka #include <asm/proc-armv/system.h>
36819833afSPeter Tyser 
37819833afSPeter Tyser #define atomic_read(v)	((v)->counter)
38819833afSPeter Tyser #define atomic_set(v, i)	(((v)->counter) = (i))
3959a51a10SAdam Oleksy #define atomic64_read(v)	atomic_read(v)
4059a51a10SAdam Oleksy #define atomic64_set(v, i)	atomic_set(v, i)
41819833afSPeter Tyser 
atomic_add(int i,volatile atomic_t * v)42819833afSPeter Tyser static inline void atomic_add(int i, volatile atomic_t *v)
43819833afSPeter Tyser {
441d48ca69SHeiko Schocher 	unsigned long flags = 0;
45819833afSPeter Tyser 
46819833afSPeter Tyser 	local_irq_save(flags);
47819833afSPeter Tyser 	v->counter += i;
48819833afSPeter Tyser 	local_irq_restore(flags);
49819833afSPeter Tyser }
50819833afSPeter Tyser 
atomic_sub(int i,volatile atomic_t * v)51819833afSPeter Tyser static inline void atomic_sub(int i, volatile atomic_t *v)
52819833afSPeter Tyser {
531d48ca69SHeiko Schocher 	unsigned long flags = 0;
54819833afSPeter Tyser 
55819833afSPeter Tyser 	local_irq_save(flags);
56819833afSPeter Tyser 	v->counter -= i;
57819833afSPeter Tyser 	local_irq_restore(flags);
58819833afSPeter Tyser }
59819833afSPeter Tyser 
atomic_inc(volatile atomic_t * v)60819833afSPeter Tyser static inline void atomic_inc(volatile atomic_t *v)
61819833afSPeter Tyser {
621d48ca69SHeiko Schocher 	unsigned long flags = 0;
63819833afSPeter Tyser 
64819833afSPeter Tyser 	local_irq_save(flags);
65819833afSPeter Tyser 	v->counter += 1;
66819833afSPeter Tyser 	local_irq_restore(flags);
67819833afSPeter Tyser }
68819833afSPeter Tyser 
atomic_dec(volatile atomic_t * v)69819833afSPeter Tyser static inline void atomic_dec(volatile atomic_t *v)
70819833afSPeter Tyser {
711d48ca69SHeiko Schocher 	unsigned long flags = 0;
72819833afSPeter Tyser 
73819833afSPeter Tyser 	local_irq_save(flags);
74819833afSPeter Tyser 	v->counter -= 1;
75819833afSPeter Tyser 	local_irq_restore(flags);
76819833afSPeter Tyser }
77819833afSPeter Tyser 
atomic_dec_and_test(volatile atomic_t * v)78819833afSPeter Tyser static inline int atomic_dec_and_test(volatile atomic_t *v)
79819833afSPeter Tyser {
801d48ca69SHeiko Schocher 	unsigned long flags = 0;
81819833afSPeter Tyser 	int val;
82819833afSPeter Tyser 
83819833afSPeter Tyser 	local_irq_save(flags);
84819833afSPeter Tyser 	val = v->counter;
85819833afSPeter Tyser 	v->counter = val -= 1;
86819833afSPeter Tyser 	local_irq_restore(flags);
87819833afSPeter Tyser 
88819833afSPeter Tyser 	return val == 0;
89819833afSPeter Tyser }
90819833afSPeter Tyser 
atomic_add_negative(int i,volatile atomic_t * v)91819833afSPeter Tyser static inline int atomic_add_negative(int i, volatile atomic_t *v)
92819833afSPeter Tyser {
931d48ca69SHeiko Schocher 	unsigned long flags = 0;
94819833afSPeter Tyser 	int val;
95819833afSPeter Tyser 
96819833afSPeter Tyser 	local_irq_save(flags);
97819833afSPeter Tyser 	val = v->counter;
98819833afSPeter Tyser 	v->counter = val += i;
99819833afSPeter Tyser 	local_irq_restore(flags);
100819833afSPeter Tyser 
101819833afSPeter Tyser 	return val < 0;
102819833afSPeter Tyser }
103819833afSPeter Tyser 
atomic_clear_mask(unsigned long mask,unsigned long * addr)104819833afSPeter Tyser static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr)
105819833afSPeter Tyser {
1061d48ca69SHeiko Schocher 	unsigned long flags = 0;
107819833afSPeter Tyser 
108819833afSPeter Tyser 	local_irq_save(flags);
109819833afSPeter Tyser 	*addr &= ~mask;
110819833afSPeter Tyser 	local_irq_restore(flags);
111819833afSPeter Tyser }
112819833afSPeter Tyser 
11359a51a10SAdam Oleksy #if BITS_PER_LONG == 32
11459a51a10SAdam Oleksy 
atomic64_add(long long i,volatile atomic64_t * v)11559a51a10SAdam Oleksy static inline void atomic64_add(long long i, volatile atomic64_t *v)
11659a51a10SAdam Oleksy {
11759a51a10SAdam Oleksy 	unsigned long flags = 0;
11859a51a10SAdam Oleksy 
11959a51a10SAdam Oleksy 	local_irq_save(flags);
12059a51a10SAdam Oleksy 	v->counter += i;
12159a51a10SAdam Oleksy 	local_irq_restore(flags);
12259a51a10SAdam Oleksy }
12359a51a10SAdam Oleksy 
atomic64_sub(long long i,volatile atomic64_t * v)12459a51a10SAdam Oleksy static inline void atomic64_sub(long long i, volatile atomic64_t *v)
12559a51a10SAdam Oleksy {
12659a51a10SAdam Oleksy 	unsigned long flags = 0;
12759a51a10SAdam Oleksy 
12859a51a10SAdam Oleksy 	local_irq_save(flags);
12959a51a10SAdam Oleksy 	v->counter -= i;
13059a51a10SAdam Oleksy 	local_irq_restore(flags);
13159a51a10SAdam Oleksy }
13259a51a10SAdam Oleksy 
13359a51a10SAdam Oleksy #else /* BIT_PER_LONG == 32 */
13459a51a10SAdam Oleksy 
atomic64_add(long i,volatile atomic64_t * v)13559a51a10SAdam Oleksy static inline void atomic64_add(long i, volatile atomic64_t *v)
13659a51a10SAdam Oleksy {
13759a51a10SAdam Oleksy 	unsigned long flags = 0;
13859a51a10SAdam Oleksy 
13959a51a10SAdam Oleksy 	local_irq_save(flags);
14059a51a10SAdam Oleksy 	v->counter += i;
14159a51a10SAdam Oleksy 	local_irq_restore(flags);
14259a51a10SAdam Oleksy }
14359a51a10SAdam Oleksy 
atomic64_sub(long i,volatile atomic64_t * v)14459a51a10SAdam Oleksy static inline void atomic64_sub(long i, volatile atomic64_t *v)
14559a51a10SAdam Oleksy {
14659a51a10SAdam Oleksy 	unsigned long flags = 0;
14759a51a10SAdam Oleksy 
14859a51a10SAdam Oleksy 	local_irq_save(flags);
14959a51a10SAdam Oleksy 	v->counter -= i;
15059a51a10SAdam Oleksy 	local_irq_restore(flags);
15159a51a10SAdam Oleksy }
15259a51a10SAdam Oleksy #endif
15359a51a10SAdam Oleksy 
atomic64_inc(volatile atomic64_t * v)15459a51a10SAdam Oleksy static inline void atomic64_inc(volatile atomic64_t *v)
15559a51a10SAdam Oleksy {
15659a51a10SAdam Oleksy 	unsigned long flags = 0;
15759a51a10SAdam Oleksy 
15859a51a10SAdam Oleksy 	local_irq_save(flags);
15959a51a10SAdam Oleksy 	v->counter += 1;
16059a51a10SAdam Oleksy 	local_irq_restore(flags);
16159a51a10SAdam Oleksy }
16259a51a10SAdam Oleksy 
atomic64_dec(volatile atomic64_t * v)16359a51a10SAdam Oleksy static inline void atomic64_dec(volatile atomic64_t *v)
16459a51a10SAdam Oleksy {
16559a51a10SAdam Oleksy 	unsigned long flags = 0;
16659a51a10SAdam Oleksy 
16759a51a10SAdam Oleksy 	local_irq_save(flags);
16859a51a10SAdam Oleksy 	v->counter -= 1;
16959a51a10SAdam Oleksy 	local_irq_restore(flags);
17059a51a10SAdam Oleksy }
17159a51a10SAdam Oleksy 
172819833afSPeter Tyser /* Atomic operations are already serializing on ARM */
173819833afSPeter Tyser #define smp_mb__before_atomic_dec()	barrier()
174819833afSPeter Tyser #define smp_mb__after_atomic_dec()	barrier()
175819833afSPeter Tyser #define smp_mb__before_atomic_inc()	barrier()
176819833afSPeter Tyser #define smp_mb__after_atomic_inc()	barrier()
177819833afSPeter Tyser 
178819833afSPeter Tyser #endif
179819833afSPeter Tyser #endif
180