Linux Audio

Check our new training course

Loading...
Note: File does not exist in v5.4.
  1/* SPDX-License-Identifier: GPL-2.0-only */
  2
  3#ifndef _ASM_ARC_ATOMIC_SPLOCK_H
  4#define _ASM_ARC_ATOMIC_SPLOCK_H
  5
  6/*
  7 * Non hardware assisted Atomic-R-M-W
  8 * Locking would change to irq-disabling only (UP) and spinlocks (SMP)
  9 */
 10
 11static inline void arch_atomic_set(atomic_t *v, int i)
 12{
 13	/*
 14	 * Independent of hardware support, all of the atomic_xxx() APIs need
 15	 * to follow the same locking rules to make sure that a "hardware"
 16	 * atomic insn (e.g. LD) doesn't clobber an "emulated" atomic insn
 17	 * sequence
 18	 *
 19	 * Thus atomic_set() despite being 1 insn (and seemingly atomic)
 20	 * requires the locking.
 21	 */
 22	unsigned long flags;
 23
 24	atomic_ops_lock(flags);
 25	WRITE_ONCE(v->counter, i);
 26	atomic_ops_unlock(flags);
 27}
 28
 29#define arch_atomic_set_release(v, i)	arch_atomic_set((v), (i))
 30
 31#define ATOMIC_OP(op, c_op, asm_op)					\
 32static inline void arch_atomic_##op(int i, atomic_t *v)			\
 33{									\
 34	unsigned long flags;						\
 35									\
 36	atomic_ops_lock(flags);						\
 37	v->counter c_op i;						\
 38	atomic_ops_unlock(flags);					\
 39}
 40
 41#define ATOMIC_OP_RETURN(op, c_op, asm_op)				\
 42static inline int arch_atomic_##op##_return(int i, atomic_t *v)		\
 43{									\
 44	unsigned long flags;						\
 45	unsigned int temp;						\
 46									\
 47	/*								\
 48	 * spin lock/unlock provides the needed smp_mb() before/after	\
 49	 */								\
 50	atomic_ops_lock(flags);						\
 51	temp = v->counter;						\
 52	temp c_op i;							\
 53	v->counter = temp;						\
 54	atomic_ops_unlock(flags);					\
 55									\
 56	return temp;							\
 57}
 58
 59#define ATOMIC_FETCH_OP(op, c_op, asm_op)				\
 60static inline int arch_atomic_fetch_##op(int i, atomic_t *v)		\
 61{									\
 62	unsigned long flags;						\
 63	unsigned int orig;						\
 64									\
 65	/*								\
 66	 * spin lock/unlock provides the needed smp_mb() before/after	\
 67	 */								\
 68	atomic_ops_lock(flags);						\
 69	orig = v->counter;						\
 70	v->counter c_op i;						\
 71	atomic_ops_unlock(flags);					\
 72									\
 73	return orig;							\
 74}
 75
 76#define ATOMIC_OPS(op, c_op, asm_op)					\
 77	ATOMIC_OP(op, c_op, asm_op)					\
 78	ATOMIC_OP_RETURN(op, c_op, asm_op)				\
 79	ATOMIC_FETCH_OP(op, c_op, asm_op)
 80
 81ATOMIC_OPS(add, +=, add)
 82ATOMIC_OPS(sub, -=, sub)
 83
 84#define arch_atomic_fetch_add		arch_atomic_fetch_add
 85#define arch_atomic_fetch_sub		arch_atomic_fetch_sub
 86#define arch_atomic_add_return		arch_atomic_add_return
 87#define arch_atomic_sub_return		arch_atomic_sub_return
 88
 89#undef ATOMIC_OPS
 90#define ATOMIC_OPS(op, c_op, asm_op)					\
 91	ATOMIC_OP(op, c_op, asm_op)					\
 92	ATOMIC_FETCH_OP(op, c_op, asm_op)
 93
 94ATOMIC_OPS(and, &=, and)
 95ATOMIC_OPS(andnot, &= ~, bic)
 96ATOMIC_OPS(or, |=, or)
 97ATOMIC_OPS(xor, ^=, xor)
 98
 99#define arch_atomic_andnot		arch_atomic_andnot
100
101#define arch_atomic_fetch_and		arch_atomic_fetch_and
102#define arch_atomic_fetch_andnot	arch_atomic_fetch_andnot
103#define arch_atomic_fetch_or		arch_atomic_fetch_or
104#define arch_atomic_fetch_xor		arch_atomic_fetch_xor
105
106#undef ATOMIC_OPS
107#undef ATOMIC_FETCH_OP
108#undef ATOMIC_OP_RETURN
109#undef ATOMIC_OP
110
111#endif