1/* SPDX-License-Identifier: GPL-2.0 */ 2#ifndef __ARCH_H8300_ATOMIC__ 3#define __ARCH_H8300_ATOMIC__ 4 5#include <linux/compiler.h> 6#include <linux/types.h> 7#include <asm/cmpxchg.h> 8#include <asm/irqflags.h> 9 10/* 11 * Atomic operations that C can't guarantee us. Useful for 12 * resource counting etc.. 13 */ 14 15#define atomic_read(v) READ_ONCE((v)->counter) 16#define atomic_set(v, i) WRITE_ONCE(((v)->counter), (i)) 17 18#define ATOMIC_OP_RETURN(op, c_op) \ 19static inline int atomic_##op##_return(int i, atomic_t *v) \ 20{ \ 21 h8300flags flags; \ 22 int ret; \ 23 \ 24 flags = arch_local_irq_save(); \ 25 ret = v->counter c_op i; \ 26 arch_local_irq_restore(flags); \ 27 return ret; \ 28} 29 30#define ATOMIC_FETCH_OP(op, c_op) \ 31static inline int atomic_fetch_##op(int i, atomic_t *v) \ 32{ \ 33 h8300flags flags; \ 34 int ret; \ 35 \ 36 flags = arch_local_irq_save(); \ 37 ret = v->counter; \ 38 v->counter c_op i; \ 39 arch_local_irq_restore(flags); \ 40 return ret; \ 41} 42 43#define ATOMIC_OP(op, c_op) \ 44static inline void atomic_##op(int i, atomic_t *v) \ 45{ \ 46 h8300flags flags; \ 47 \ 48 flags = arch_local_irq_save(); \ 49 v->counter c_op i; \ 50 arch_local_irq_restore(flags); \ 51} 52 53ATOMIC_OP_RETURN(add, +=) 54ATOMIC_OP_RETURN(sub, -=) 55 56#define ATOMIC_OPS(op, c_op) \ 57 ATOMIC_OP(op, c_op) \ 58 ATOMIC_FETCH_OP(op, c_op) 59 60ATOMIC_OPS(and, &=) 61ATOMIC_OPS(or, |=) 62ATOMIC_OPS(xor, ^=) 63ATOMIC_OPS(add, +=) 64ATOMIC_OPS(sub, -=) 65 66#undef ATOMIC_OPS 67#undef ATOMIC_OP_RETURN 68#undef ATOMIC_OP 69 70static inline int atomic_cmpxchg(atomic_t *v, int old, int new) 71{ 72 int ret; 73 h8300flags flags; 74 75 flags = arch_local_irq_save(); 76 ret = v->counter; 77 if (likely(ret == old)) 78 v->counter = new; 79 arch_local_irq_restore(flags); 80 return ret; 81} 82 83static inline int atomic_fetch_add_unless(atomic_t *v, int a, int u) 84{ 85 int ret; 86 h8300flags flags; 87 88 flags = arch_local_irq_save(); 89 ret = v->counter; 90 if (ret != u) 91 v->counter += a; 92 arch_local_irq_restore(flags); 93 return ret; 94} 95#define atomic_fetch_add_unless atomic_fetch_add_unless 96 97#endif /* __ARCH_H8300_ATOMIC __ */ 98