Implement three atomic functions to allow making an atomic operation that returns the value. Adds: atomic_add_return(), atomic_sub_return(), atomic_inc_return() and atomic_dec_return().
This is heavily based on the Linux implementation of such functions for ARM. Signed-off-by: Antoine Tenart <antoine.ten...@free-electrons.com> Cc: Albert Aribaud <albert.u.b...@aribaud.net> Cc: Mark Rutland <mark.rutl...@arm.com> --- arch/arm/include/asm/atomic.h | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/arch/arm/include/asm/atomic.h b/arch/arm/include/asm/atomic.h index 171f4d979281..4bfe62afaca1 100644 --- a/arch/arm/include/asm/atomic.h +++ b/arch/arm/include/asm/atomic.h @@ -73,6 +73,42 @@ static inline void atomic_dec(volatile atomic_t *v) local_irq_restore(flags); } +#define ATOMIC_OP_RETURN(op, c_op, asm_op) \ +static inline int atomic_##op##_return(int i, volatile atomic_t *v) \ +{ \ + unsigned long tmp; \ + int result; \ + \ + /* prefetch */ \ + __asm__ __volatile__("pld\t%a0" \ + :: "p" (&v->counter)); \ + \ + __asm__ __volatile__("@ atomic_" #op "_return\n" \ +"1: ldrex %0, [%3]\n" \ +" " #asm_op " %0, %0, %4\n" \ +" strex %1, %0, [%3]\n" \ +" teq %1, #0\n" \ +" bne 1b" \ + : "=&r" (result), "=&r" (tmp), "+Qo" (v->counter) \ + : "r" (&v->counter), "Ir" (i) \ + : "cc"); \ + \ + return result; \ +} + +ATOMIC_OP_RETURN(add, +=, add) +ATOMIC_OP_RETURN(sub, -=, sub) + +static inline int atomic_inc_return(volatile atomic_t *v) +{ + return atomic_add_return(1, v); +} + +static inline int atomic_dec_return(volatile atomic_t *v) +{ + return atomic_sub_return(1, v); +} + static inline int atomic_dec_and_test(volatile atomic_t *v) { unsigned long flags = 0; -- 2.11.0 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot