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