1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */ 27f30491cSTony Luck #ifndef _ASM_IA64_ATOMIC_H 37f30491cSTony Luck #define _ASM_IA64_ATOMIC_H 47f30491cSTony Luck 57f30491cSTony Luck /* 67f30491cSTony Luck * Atomic operations that C can't guarantee us. Useful for 77f30491cSTony Luck * resource counting etc.. 87f30491cSTony Luck * 97f30491cSTony Luck * NOTE: don't mess with the types below! The "unsigned long" and 107f30491cSTony Luck * "int" types were carefully placed so as to ensure proper operation 117f30491cSTony Luck * of the macros. 127f30491cSTony Luck * 137f30491cSTony Luck * Copyright (C) 1998, 1999, 2002-2003 Hewlett-Packard Co 147f30491cSTony Luck * David Mosberger-Tang <davidm@hpl.hp.com> 157f30491cSTony Luck */ 167f30491cSTony Luck #include <linux/types.h> 177f30491cSTony Luck 187f30491cSTony Luck #include <asm/intrinsics.h> 190cd64efbSPeter Zijlstra #include <asm/barrier.h> 207f30491cSTony Luck 217f30491cSTony Luck 22a1193655STony Luck #define ATOMIC64_INIT(i) { (i) } 237f30491cSTony Luck 24*f84f1b9cSMark Rutland #define arch_atomic_read(v) READ_ONCE((v)->counter) 25*f84f1b9cSMark Rutland #define arch_atomic64_read(v) READ_ONCE((v)->counter) 267f30491cSTony Luck 27*f84f1b9cSMark Rutland #define arch_atomic_set(v,i) WRITE_ONCE(((v)->counter), (i)) 28*f84f1b9cSMark Rutland #define arch_atomic64_set(v,i) WRITE_ONCE(((v)->counter), (i)) 297f30491cSTony Luck 3008be2dabSPeter Zijlstra #define ATOMIC_OP(op, c_op) \ 3108be2dabSPeter Zijlstra static __inline__ int \ 3208be2dabSPeter Zijlstra ia64_atomic_##op (int i, atomic_t *v) \ 3308be2dabSPeter Zijlstra { \ 3408be2dabSPeter Zijlstra __s32 old, new; \ 3508be2dabSPeter Zijlstra CMPXCHG_BUGCHECK_DECL \ 3608be2dabSPeter Zijlstra \ 3708be2dabSPeter Zijlstra do { \ 3808be2dabSPeter Zijlstra CMPXCHG_BUGCHECK(v); \ 39*f84f1b9cSMark Rutland old = arch_atomic_read(v); \ 4008be2dabSPeter Zijlstra new = old c_op i; \ 4108be2dabSPeter Zijlstra } while (ia64_cmpxchg(acq, v, old, new, sizeof(atomic_t)) != old); \ 4208be2dabSPeter Zijlstra return new; \ 437f30491cSTony Luck } 447f30491cSTony Luck 45cc102507SPeter Zijlstra #define ATOMIC_FETCH_OP(op, c_op) \ 46cc102507SPeter Zijlstra static __inline__ int \ 47cc102507SPeter Zijlstra ia64_atomic_fetch_##op (int i, atomic_t *v) \ 48cc102507SPeter Zijlstra { \ 49cc102507SPeter Zijlstra __s32 old, new; \ 50cc102507SPeter Zijlstra CMPXCHG_BUGCHECK_DECL \ 51cc102507SPeter Zijlstra \ 52cc102507SPeter Zijlstra do { \ 53cc102507SPeter Zijlstra CMPXCHG_BUGCHECK(v); \ 54*f84f1b9cSMark Rutland old = arch_atomic_read(v); \ 55cc102507SPeter Zijlstra new = old c_op i; \ 56cc102507SPeter Zijlstra } while (ia64_cmpxchg(acq, v, old, new, sizeof(atomic_t)) != old); \ 57cc102507SPeter Zijlstra return old; \ 58cc102507SPeter Zijlstra } 59cc102507SPeter Zijlstra 60cc102507SPeter Zijlstra #define ATOMIC_OPS(op, c_op) \ 61cc102507SPeter Zijlstra ATOMIC_OP(op, c_op) \ 62cc102507SPeter Zijlstra ATOMIC_FETCH_OP(op, c_op) 63cc102507SPeter Zijlstra 64cc102507SPeter Zijlstra ATOMIC_OPS(add, +) 65cc102507SPeter Zijlstra ATOMIC_OPS(sub, -) 667f30491cSTony Luck 674b664e73SMatthew Wilcox #ifdef __OPTIMIZE__ 682879b65fSMatthew Wilcox #define __ia64_atomic_const(i) \ 692879b65fSMatthew Wilcox static const int __ia64_atomic_p = __builtin_constant_p(i) ? \ 704b664e73SMatthew Wilcox ((i) == 1 || (i) == 4 || (i) == 8 || (i) == 16 || \ 712879b65fSMatthew Wilcox (i) == -1 || (i) == -4 || (i) == -8 || (i) == -16) : 0;\ 722879b65fSMatthew Wilcox __ia64_atomic_p 732879b65fSMatthew Wilcox #else 742879b65fSMatthew Wilcox #define __ia64_atomic_const(i) 0 752879b65fSMatthew Wilcox #endif 764b664e73SMatthew Wilcox 77*f84f1b9cSMark Rutland #define arch_atomic_add_return(i,v) \ 7808be2dabSPeter Zijlstra ({ \ 792879b65fSMatthew Wilcox int __ia64_aar_i = (i); \ 802879b65fSMatthew Wilcox __ia64_atomic_const(i) \ 812879b65fSMatthew Wilcox ? ia64_fetch_and_add(__ia64_aar_i, &(v)->counter) \ 822879b65fSMatthew Wilcox : ia64_atomic_add(__ia64_aar_i, v); \ 8308be2dabSPeter Zijlstra }) 8408be2dabSPeter Zijlstra 85*f84f1b9cSMark Rutland #define arch_atomic_sub_return(i,v) \ 8608be2dabSPeter Zijlstra ({ \ 872879b65fSMatthew Wilcox int __ia64_asr_i = (i); \ 882879b65fSMatthew Wilcox __ia64_atomic_const(i) \ 892879b65fSMatthew Wilcox ? ia64_fetch_and_add(-__ia64_asr_i, &(v)->counter) \ 902879b65fSMatthew Wilcox : ia64_atomic_sub(__ia64_asr_i, v); \ 9108be2dabSPeter Zijlstra }) 9208be2dabSPeter Zijlstra 93*f84f1b9cSMark Rutland #define arch_atomic_fetch_add(i,v) \ 94cc102507SPeter Zijlstra ({ \ 95cc102507SPeter Zijlstra int __ia64_aar_i = (i); \ 962879b65fSMatthew Wilcox __ia64_atomic_const(i) \ 97cc102507SPeter Zijlstra ? ia64_fetchadd(__ia64_aar_i, &(v)->counter, acq) \ 98cc102507SPeter Zijlstra : ia64_atomic_fetch_add(__ia64_aar_i, v); \ 99cc102507SPeter Zijlstra }) 10070ed4739SPeter Zijlstra 101*f84f1b9cSMark Rutland #define arch_atomic_fetch_sub(i,v) \ 102cc102507SPeter Zijlstra ({ \ 103cc102507SPeter Zijlstra int __ia64_asr_i = (i); \ 1042879b65fSMatthew Wilcox __ia64_atomic_const(i) \ 105cc102507SPeter Zijlstra ? ia64_fetchadd(-__ia64_asr_i, &(v)->counter, acq) \ 106cc102507SPeter Zijlstra : ia64_atomic_fetch_sub(__ia64_asr_i, v); \ 107cc102507SPeter Zijlstra }) 10870ed4739SPeter Zijlstra 109cc102507SPeter Zijlstra ATOMIC_FETCH_OP(and, &) 110cc102507SPeter Zijlstra ATOMIC_FETCH_OP(or, |) 111cc102507SPeter Zijlstra ATOMIC_FETCH_OP(xor, ^) 112cc102507SPeter Zijlstra 113*f84f1b9cSMark Rutland #define arch_atomic_and(i,v) (void)ia64_atomic_fetch_and(i,v) 114*f84f1b9cSMark Rutland #define arch_atomic_or(i,v) (void)ia64_atomic_fetch_or(i,v) 115*f84f1b9cSMark Rutland #define arch_atomic_xor(i,v) (void)ia64_atomic_fetch_xor(i,v) 116cc102507SPeter Zijlstra 117*f84f1b9cSMark Rutland #define arch_atomic_fetch_and(i,v) ia64_atomic_fetch_and(i,v) 118*f84f1b9cSMark Rutland #define arch_atomic_fetch_or(i,v) ia64_atomic_fetch_or(i,v) 119*f84f1b9cSMark Rutland #define arch_atomic_fetch_xor(i,v) ia64_atomic_fetch_xor(i,v) 120cc102507SPeter Zijlstra 121cc102507SPeter Zijlstra #undef ATOMIC_OPS 122cc102507SPeter Zijlstra #undef ATOMIC_FETCH_OP 12370ed4739SPeter Zijlstra #undef ATOMIC_OP 12470ed4739SPeter Zijlstra 12508be2dabSPeter Zijlstra #define ATOMIC64_OP(op, c_op) \ 126d84e28d2SMark Rutland static __inline__ s64 \ 127d84e28d2SMark Rutland ia64_atomic64_##op (s64 i, atomic64_t *v) \ 12808be2dabSPeter Zijlstra { \ 129d84e28d2SMark Rutland s64 old, new; \ 13008be2dabSPeter Zijlstra CMPXCHG_BUGCHECK_DECL \ 13108be2dabSPeter Zijlstra \ 13208be2dabSPeter Zijlstra do { \ 13308be2dabSPeter Zijlstra CMPXCHG_BUGCHECK(v); \ 134*f84f1b9cSMark Rutland old = arch_atomic64_read(v); \ 13508be2dabSPeter Zijlstra new = old c_op i; \ 13608be2dabSPeter Zijlstra } while (ia64_cmpxchg(acq, v, old, new, sizeof(atomic64_t)) != old); \ 13708be2dabSPeter Zijlstra return new; \ 1387f30491cSTony Luck } 1397f30491cSTony Luck 140cc102507SPeter Zijlstra #define ATOMIC64_FETCH_OP(op, c_op) \ 141d84e28d2SMark Rutland static __inline__ s64 \ 142d84e28d2SMark Rutland ia64_atomic64_fetch_##op (s64 i, atomic64_t *v) \ 143cc102507SPeter Zijlstra { \ 144d84e28d2SMark Rutland s64 old, new; \ 145cc102507SPeter Zijlstra CMPXCHG_BUGCHECK_DECL \ 146cc102507SPeter Zijlstra \ 147cc102507SPeter Zijlstra do { \ 148cc102507SPeter Zijlstra CMPXCHG_BUGCHECK(v); \ 149*f84f1b9cSMark Rutland old = arch_atomic64_read(v); \ 150cc102507SPeter Zijlstra new = old c_op i; \ 151cc102507SPeter Zijlstra } while (ia64_cmpxchg(acq, v, old, new, sizeof(atomic64_t)) != old); \ 152cc102507SPeter Zijlstra return old; \ 153cc102507SPeter Zijlstra } 154cc102507SPeter Zijlstra 155cc102507SPeter Zijlstra #define ATOMIC64_OPS(op, c_op) \ 156cc102507SPeter Zijlstra ATOMIC64_OP(op, c_op) \ 157cc102507SPeter Zijlstra ATOMIC64_FETCH_OP(op, c_op) 158cc102507SPeter Zijlstra 159cc102507SPeter Zijlstra ATOMIC64_OPS(add, +) 160cc102507SPeter Zijlstra ATOMIC64_OPS(sub, -) 1617f30491cSTony Luck 162*f84f1b9cSMark Rutland #define arch_atomic64_add_return(i,v) \ 16308be2dabSPeter Zijlstra ({ \ 164d84e28d2SMark Rutland s64 __ia64_aar_i = (i); \ 1652879b65fSMatthew Wilcox __ia64_atomic_const(i) \ 16608be2dabSPeter Zijlstra ? ia64_fetch_and_add(__ia64_aar_i, &(v)->counter) \ 16708be2dabSPeter Zijlstra : ia64_atomic64_add(__ia64_aar_i, v); \ 16808be2dabSPeter Zijlstra }) 1697f30491cSTony Luck 170*f84f1b9cSMark Rutland #define arch_atomic64_sub_return(i,v) \ 17108be2dabSPeter Zijlstra ({ \ 172d84e28d2SMark Rutland s64 __ia64_asr_i = (i); \ 1732879b65fSMatthew Wilcox __ia64_atomic_const(i) \ 17408be2dabSPeter Zijlstra ? ia64_fetch_and_add(-__ia64_asr_i, &(v)->counter) \ 17508be2dabSPeter Zijlstra : ia64_atomic64_sub(__ia64_asr_i, v); \ 17608be2dabSPeter Zijlstra }) 1777f30491cSTony Luck 178*f84f1b9cSMark Rutland #define arch_atomic64_fetch_add(i,v) \ 179cc102507SPeter Zijlstra ({ \ 180d84e28d2SMark Rutland s64 __ia64_aar_i = (i); \ 1812879b65fSMatthew Wilcox __ia64_atomic_const(i) \ 182cc102507SPeter Zijlstra ? ia64_fetchadd(__ia64_aar_i, &(v)->counter, acq) \ 183cc102507SPeter Zijlstra : ia64_atomic64_fetch_add(__ia64_aar_i, v); \ 184cc102507SPeter Zijlstra }) 18570ed4739SPeter Zijlstra 186*f84f1b9cSMark Rutland #define arch_atomic64_fetch_sub(i,v) \ 187cc102507SPeter Zijlstra ({ \ 188d84e28d2SMark Rutland s64 __ia64_asr_i = (i); \ 1892879b65fSMatthew Wilcox __ia64_atomic_const(i) \ 190cc102507SPeter Zijlstra ? ia64_fetchadd(-__ia64_asr_i, &(v)->counter, acq) \ 191cc102507SPeter Zijlstra : ia64_atomic64_fetch_sub(__ia64_asr_i, v); \ 192cc102507SPeter Zijlstra }) 19370ed4739SPeter Zijlstra 194cc102507SPeter Zijlstra ATOMIC64_FETCH_OP(and, &) 195cc102507SPeter Zijlstra ATOMIC64_FETCH_OP(or, |) 196cc102507SPeter Zijlstra ATOMIC64_FETCH_OP(xor, ^) 197cc102507SPeter Zijlstra 198*f84f1b9cSMark Rutland #define arch_atomic64_and(i,v) (void)ia64_atomic64_fetch_and(i,v) 199*f84f1b9cSMark Rutland #define arch_atomic64_or(i,v) (void)ia64_atomic64_fetch_or(i,v) 200*f84f1b9cSMark Rutland #define arch_atomic64_xor(i,v) (void)ia64_atomic64_fetch_xor(i,v) 201cc102507SPeter Zijlstra 202*f84f1b9cSMark Rutland #define arch_atomic64_fetch_and(i,v) ia64_atomic64_fetch_and(i,v) 203*f84f1b9cSMark Rutland #define arch_atomic64_fetch_or(i,v) ia64_atomic64_fetch_or(i,v) 204*f84f1b9cSMark Rutland #define arch_atomic64_fetch_xor(i,v) ia64_atomic64_fetch_xor(i,v) 205cc102507SPeter Zijlstra 206cc102507SPeter Zijlstra #undef ATOMIC64_OPS 207cc102507SPeter Zijlstra #undef ATOMIC64_FETCH_OP 20870ed4739SPeter Zijlstra #undef ATOMIC64_OP 20970ed4739SPeter Zijlstra 210*f84f1b9cSMark Rutland #define arch_atomic_add(i,v) (void)arch_atomic_add_return((i), (v)) 211*f84f1b9cSMark Rutland #define arch_atomic_sub(i,v) (void)arch_atomic_sub_return((i), (v)) 2127f30491cSTony Luck 213*f84f1b9cSMark Rutland #define arch_atomic64_add(i,v) (void)arch_atomic64_add_return((i), (v)) 214*f84f1b9cSMark Rutland #define arch_atomic64_sub(i,v) (void)arch_atomic64_sub_return((i), (v)) 2157f30491cSTony Luck 2167f30491cSTony Luck #endif /* _ASM_IA64_ATOMIC_H */ 217