xref: /rk3399_rockchip-uboot/arch/powerpc/include/asm/atomic.h (revision a47a12becf66f02a56da91c161e2edb625e9f20c)
1*a47a12beSStefan Roese /*
2*a47a12beSStefan Roese  * PowerPC atomic operations
3*a47a12beSStefan Roese  */
4*a47a12beSStefan Roese 
5*a47a12beSStefan Roese #ifndef _ASM_PPC_ATOMIC_H_
6*a47a12beSStefan Roese #define _ASM_PPC_ATOMIC_H_
7*a47a12beSStefan Roese 
8*a47a12beSStefan Roese #include <linux/config.h>
9*a47a12beSStefan Roese 
10*a47a12beSStefan Roese #ifdef CONFIG_SMP
11*a47a12beSStefan Roese typedef struct { volatile int counter; } atomic_t;
12*a47a12beSStefan Roese #else
13*a47a12beSStefan Roese typedef struct { int counter; } atomic_t;
14*a47a12beSStefan Roese #endif
15*a47a12beSStefan Roese 
16*a47a12beSStefan Roese #define ATOMIC_INIT(i)	{ (i) }
17*a47a12beSStefan Roese 
18*a47a12beSStefan Roese #define atomic_read(v)		((v)->counter)
19*a47a12beSStefan Roese #define atomic_set(v,i)		(((v)->counter) = (i))
20*a47a12beSStefan Roese 
21*a47a12beSStefan Roese extern void atomic_clear_mask(unsigned long mask, unsigned long *addr);
22*a47a12beSStefan Roese extern void atomic_set_mask(unsigned long mask, unsigned long *addr);
23*a47a12beSStefan Roese 
24*a47a12beSStefan Roese extern __inline__ int atomic_add_return(int a, atomic_t *v)
25*a47a12beSStefan Roese {
26*a47a12beSStefan Roese 	int t;
27*a47a12beSStefan Roese 
28*a47a12beSStefan Roese 	__asm__ __volatile__("\n\
29*a47a12beSStefan Roese 1:	lwarx	%0,0,%3\n\
30*a47a12beSStefan Roese 	add	%0,%2,%0\n\
31*a47a12beSStefan Roese 	stwcx.	%0,0,%3\n\
32*a47a12beSStefan Roese 	bne-	1b"
33*a47a12beSStefan Roese 	: "=&r" (t), "=m" (*v)
34*a47a12beSStefan Roese 	: "r" (a), "r" (v), "m" (*v)
35*a47a12beSStefan Roese 	: "cc");
36*a47a12beSStefan Roese 
37*a47a12beSStefan Roese 	return t;
38*a47a12beSStefan Roese }
39*a47a12beSStefan Roese 
40*a47a12beSStefan Roese extern __inline__ int atomic_sub_return(int a, atomic_t *v)
41*a47a12beSStefan Roese {
42*a47a12beSStefan Roese 	int t;
43*a47a12beSStefan Roese 
44*a47a12beSStefan Roese 	__asm__ __volatile__("\n\
45*a47a12beSStefan Roese 1:	lwarx	%0,0,%3\n\
46*a47a12beSStefan Roese 	subf	%0,%2,%0\n\
47*a47a12beSStefan Roese 	stwcx.	%0,0,%3\n\
48*a47a12beSStefan Roese 	bne-	1b"
49*a47a12beSStefan Roese 	: "=&r" (t), "=m" (*v)
50*a47a12beSStefan Roese 	: "r" (a), "r" (v), "m" (*v)
51*a47a12beSStefan Roese 	: "cc");
52*a47a12beSStefan Roese 
53*a47a12beSStefan Roese 	return t;
54*a47a12beSStefan Roese }
55*a47a12beSStefan Roese 
56*a47a12beSStefan Roese extern __inline__ int atomic_inc_return(atomic_t *v)
57*a47a12beSStefan Roese {
58*a47a12beSStefan Roese 	int t;
59*a47a12beSStefan Roese 
60*a47a12beSStefan Roese 	__asm__ __volatile__("\n\
61*a47a12beSStefan Roese 1:	lwarx	%0,0,%2\n\
62*a47a12beSStefan Roese 	addic	%0,%0,1\n\
63*a47a12beSStefan Roese 	stwcx.	%0,0,%2\n\
64*a47a12beSStefan Roese 	bne-	1b"
65*a47a12beSStefan Roese 	: "=&r" (t), "=m" (*v)
66*a47a12beSStefan Roese 	: "r" (v), "m" (*v)
67*a47a12beSStefan Roese 	: "cc");
68*a47a12beSStefan Roese 
69*a47a12beSStefan Roese 	return t;
70*a47a12beSStefan Roese }
71*a47a12beSStefan Roese 
72*a47a12beSStefan Roese extern __inline__ int atomic_dec_return(atomic_t *v)
73*a47a12beSStefan Roese {
74*a47a12beSStefan Roese 	int t;
75*a47a12beSStefan Roese 
76*a47a12beSStefan Roese 	__asm__ __volatile__("\n\
77*a47a12beSStefan Roese 1:	lwarx	%0,0,%2\n\
78*a47a12beSStefan Roese 	addic	%0,%0,-1\n\
79*a47a12beSStefan Roese 	stwcx.	%0,0,%2\n\
80*a47a12beSStefan Roese 	bne	1b"
81*a47a12beSStefan Roese 	: "=&r" (t), "=m" (*v)
82*a47a12beSStefan Roese 	: "r" (v), "m" (*v)
83*a47a12beSStefan Roese 	: "cc");
84*a47a12beSStefan Roese 
85*a47a12beSStefan Roese 	return t;
86*a47a12beSStefan Roese }
87*a47a12beSStefan Roese 
88*a47a12beSStefan Roese #define atomic_add(a, v)		((void) atomic_add_return((a), (v)))
89*a47a12beSStefan Roese #define atomic_sub(a, v)		((void) atomic_sub_return((a), (v)))
90*a47a12beSStefan Roese #define atomic_sub_and_test(a, v)	(atomic_sub_return((a), (v)) == 0)
91*a47a12beSStefan Roese #define atomic_inc(v)			((void) atomic_inc_return((v)))
92*a47a12beSStefan Roese #define atomic_dec(v)			((void) atomic_dec_return((v)))
93*a47a12beSStefan Roese #define atomic_dec_and_test(v)		(atomic_dec_return((v)) == 0)
94*a47a12beSStefan Roese 
95*a47a12beSStefan Roese #endif /* _ASM_PPC_ATOMIC_H_ */
96