1 /* SPDX-License-Identifier: GPL-2.0 */
3 * Copyright (C) 2020-2022 Loongson Technology Corporation Limited
5 #ifndef __ASM_CMPXCHG_H
6 #define __ASM_CMPXCHG_H
8 #include <asm/barrier.h>
9 #include <linux/build_bug.h>
11 #define __xchg_asm(amswap_db, m, val) \
13 __typeof(val) __ret; \
15 __asm__ __volatile__ ( \
16 " "amswap_db" %1, %z2, %0 \n" \
17 : "+ZB" (*m), "=&r" (__ret) \
24 static inline unsigned long __xchg(volatile void *ptr, unsigned long x,
29 return __xchg_asm("amswap_db.w", (volatile u32 *)ptr, (u32)x);
32 return __xchg_asm("amswap_db.d", (volatile u64 *)ptr, (u64)x);
41 #define arch_xchg(ptr, x) \
43 __typeof__(*(ptr)) __res; \
45 __res = (__typeof__(*(ptr))) \
46 __xchg((ptr), (unsigned long)(x), sizeof(*(ptr))); \
51 #define __cmpxchg_asm(ld, st, m, old, new) \
53 __typeof(old) __ret; \
55 __asm__ __volatile__( \
56 "1: " ld " %0, %2 # __cmpxchg_asm \n" \
57 " bne %0, %z3, 2f \n" \
58 " or $t0, %z4, $zero \n" \
59 " " st " $t0, %1 \n" \
60 " beq $zero, $t0, 1b \n" \
63 : "=&r" (__ret), "=ZB"(*m) \
64 : "ZB"(*m), "Jr" (old), "Jr" (new) \
70 static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
71 unsigned long new, unsigned int size)
75 return __cmpxchg_asm("ll.w", "sc.w", (volatile u32 *)ptr,
79 return __cmpxchg_asm("ll.d", "sc.d", (volatile u64 *)ptr,
89 #define arch_cmpxchg_local(ptr, old, new) \
90 ((__typeof__(*(ptr))) \
92 (unsigned long)(__typeof__(*(ptr)))(old), \
93 (unsigned long)(__typeof__(*(ptr)))(new), \
96 #define arch_cmpxchg(ptr, old, new) \
98 __typeof__(*(ptr)) __res; \
100 __res = arch_cmpxchg_local((ptr), (old), (new)); \
106 #define arch_cmpxchg64_local(ptr, o, n) \
108 BUILD_BUG_ON(sizeof(*(ptr)) != 8); \
109 arch_cmpxchg_local((ptr), (o), (n)); \
112 #define arch_cmpxchg64(ptr, o, n) \
114 BUILD_BUG_ON(sizeof(*(ptr)) != 8); \
115 arch_cmpxchg((ptr), (o), (n)); \
118 #include <asm-generic/cmpxchg-local.h>
119 #define arch_cmpxchg64_local(ptr, o, n) __generic_cmpxchg64_local((ptr), (o), (n))
120 #define arch_cmpxchg64(ptr, o, n) arch_cmpxchg64_local((ptr), (o), (n))
123 #endif /* __ASM_CMPXCHG_H */