162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci#ifndef _ASM_POWERPC_CMPXCHG_H_
362306a36Sopenharmony_ci#define _ASM_POWERPC_CMPXCHG_H_
462306a36Sopenharmony_ci
562306a36Sopenharmony_ci#ifdef __KERNEL__
662306a36Sopenharmony_ci#include <linux/compiler.h>
762306a36Sopenharmony_ci#include <asm/synch.h>
862306a36Sopenharmony_ci#include <linux/bug.h>
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci#ifdef __BIG_ENDIAN
1162306a36Sopenharmony_ci#define BITOFF_CAL(size, off)	((sizeof(u32) - size - off) * BITS_PER_BYTE)
1262306a36Sopenharmony_ci#else
1362306a36Sopenharmony_ci#define BITOFF_CAL(size, off)	(off * BITS_PER_BYTE)
1462306a36Sopenharmony_ci#endif
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ci#define XCHG_GEN(type, sfx, cl)				\
1762306a36Sopenharmony_cistatic inline u32 __xchg_##type##sfx(volatile void *p, u32 val)	\
1862306a36Sopenharmony_ci{								\
1962306a36Sopenharmony_ci	unsigned int prev, prev_mask, tmp, bitoff, off;		\
2062306a36Sopenharmony_ci								\
2162306a36Sopenharmony_ci	off = (unsigned long)p % sizeof(u32);			\
2262306a36Sopenharmony_ci	bitoff = BITOFF_CAL(sizeof(type), off);			\
2362306a36Sopenharmony_ci	p -= off;						\
2462306a36Sopenharmony_ci	val <<= bitoff;						\
2562306a36Sopenharmony_ci	prev_mask = (u32)(type)-1 << bitoff;			\
2662306a36Sopenharmony_ci								\
2762306a36Sopenharmony_ci	__asm__ __volatile__(					\
2862306a36Sopenharmony_ci"1:	lwarx   %0,0,%3\n"					\
2962306a36Sopenharmony_ci"	andc	%1,%0,%5\n"					\
3062306a36Sopenharmony_ci"	or	%1,%1,%4\n"					\
3162306a36Sopenharmony_ci"	stwcx.	%1,0,%3\n"					\
3262306a36Sopenharmony_ci"	bne-	1b\n"						\
3362306a36Sopenharmony_ci	: "=&r" (prev), "=&r" (tmp), "+m" (*(u32*)p)		\
3462306a36Sopenharmony_ci	: "r" (p), "r" (val), "r" (prev_mask)			\
3562306a36Sopenharmony_ci	: "cc", cl);						\
3662306a36Sopenharmony_ci								\
3762306a36Sopenharmony_ci	return prev >> bitoff;					\
3862306a36Sopenharmony_ci}
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_ci#define CMPXCHG_GEN(type, sfx, br, br2, cl)			\
4162306a36Sopenharmony_cistatic inline							\
4262306a36Sopenharmony_ciu32 __cmpxchg_##type##sfx(volatile void *p, u32 old, u32 new)	\
4362306a36Sopenharmony_ci{								\
4462306a36Sopenharmony_ci	unsigned int prev, prev_mask, tmp, bitoff, off;		\
4562306a36Sopenharmony_ci								\
4662306a36Sopenharmony_ci	off = (unsigned long)p % sizeof(u32);			\
4762306a36Sopenharmony_ci	bitoff = BITOFF_CAL(sizeof(type), off);			\
4862306a36Sopenharmony_ci	p -= off;						\
4962306a36Sopenharmony_ci	old <<= bitoff;						\
5062306a36Sopenharmony_ci	new <<= bitoff;						\
5162306a36Sopenharmony_ci	prev_mask = (u32)(type)-1 << bitoff;			\
5262306a36Sopenharmony_ci								\
5362306a36Sopenharmony_ci	__asm__ __volatile__(					\
5462306a36Sopenharmony_ci	br							\
5562306a36Sopenharmony_ci"1:	lwarx   %0,0,%3\n"					\
5662306a36Sopenharmony_ci"	and	%1,%0,%6\n"					\
5762306a36Sopenharmony_ci"	cmpw	0,%1,%4\n"					\
5862306a36Sopenharmony_ci"	bne-	2f\n"						\
5962306a36Sopenharmony_ci"	andc	%1,%0,%6\n"					\
6062306a36Sopenharmony_ci"	or	%1,%1,%5\n"					\
6162306a36Sopenharmony_ci"	stwcx.  %1,0,%3\n"					\
6262306a36Sopenharmony_ci"	bne-    1b\n"						\
6362306a36Sopenharmony_ci	br2							\
6462306a36Sopenharmony_ci	"\n"							\
6562306a36Sopenharmony_ci"2:"								\
6662306a36Sopenharmony_ci	: "=&r" (prev), "=&r" (tmp), "+m" (*(u32*)p)		\
6762306a36Sopenharmony_ci	: "r" (p), "r" (old), "r" (new), "r" (prev_mask)	\
6862306a36Sopenharmony_ci	: "cc", cl);						\
6962306a36Sopenharmony_ci								\
7062306a36Sopenharmony_ci	return prev >> bitoff;					\
7162306a36Sopenharmony_ci}
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_ci/*
7462306a36Sopenharmony_ci * Atomic exchange
7562306a36Sopenharmony_ci *
7662306a36Sopenharmony_ci * Changes the memory location '*p' to be val and returns
7762306a36Sopenharmony_ci * the previous value stored there.
7862306a36Sopenharmony_ci */
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_ci#ifndef CONFIG_PPC_HAS_LBARX_LHARX
8162306a36Sopenharmony_ciXCHG_GEN(u8, _local, "memory");
8262306a36Sopenharmony_ciXCHG_GEN(u8, _relaxed, "cc");
8362306a36Sopenharmony_ciXCHG_GEN(u16, _local, "memory");
8462306a36Sopenharmony_ciXCHG_GEN(u16, _relaxed, "cc");
8562306a36Sopenharmony_ci#else
8662306a36Sopenharmony_cistatic __always_inline unsigned long
8762306a36Sopenharmony_ci__xchg_u8_local(volatile void *p, unsigned long val)
8862306a36Sopenharmony_ci{
8962306a36Sopenharmony_ci	unsigned long prev;
9062306a36Sopenharmony_ci
9162306a36Sopenharmony_ci	__asm__ __volatile__(
9262306a36Sopenharmony_ci"1:	lbarx	%0,0,%2		# __xchg_u8_local\n"
9362306a36Sopenharmony_ci"	stbcx.	%3,0,%2 \n"
9462306a36Sopenharmony_ci"	bne-	1b"
9562306a36Sopenharmony_ci	: "=&r" (prev), "+m" (*(volatile unsigned char *)p)
9662306a36Sopenharmony_ci	: "r" (p), "r" (val)
9762306a36Sopenharmony_ci	: "cc", "memory");
9862306a36Sopenharmony_ci
9962306a36Sopenharmony_ci	return prev;
10062306a36Sopenharmony_ci}
10162306a36Sopenharmony_ci
10262306a36Sopenharmony_cistatic __always_inline unsigned long
10362306a36Sopenharmony_ci__xchg_u8_relaxed(u8 *p, unsigned long val)
10462306a36Sopenharmony_ci{
10562306a36Sopenharmony_ci	unsigned long prev;
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_ci	__asm__ __volatile__(
10862306a36Sopenharmony_ci"1:	lbarx	%0,0,%2		# __xchg_u8_relaxed\n"
10962306a36Sopenharmony_ci"	stbcx.	%3,0,%2\n"
11062306a36Sopenharmony_ci"	bne-	1b"
11162306a36Sopenharmony_ci	: "=&r" (prev), "+m" (*p)
11262306a36Sopenharmony_ci	: "r" (p), "r" (val)
11362306a36Sopenharmony_ci	: "cc");
11462306a36Sopenharmony_ci
11562306a36Sopenharmony_ci	return prev;
11662306a36Sopenharmony_ci}
11762306a36Sopenharmony_ci
11862306a36Sopenharmony_cistatic __always_inline unsigned long
11962306a36Sopenharmony_ci__xchg_u16_local(volatile void *p, unsigned long val)
12062306a36Sopenharmony_ci{
12162306a36Sopenharmony_ci	unsigned long prev;
12262306a36Sopenharmony_ci
12362306a36Sopenharmony_ci	__asm__ __volatile__(
12462306a36Sopenharmony_ci"1:	lharx	%0,0,%2		# __xchg_u16_local\n"
12562306a36Sopenharmony_ci"	sthcx.	%3,0,%2\n"
12662306a36Sopenharmony_ci"	bne-	1b"
12762306a36Sopenharmony_ci	: "=&r" (prev), "+m" (*(volatile unsigned short *)p)
12862306a36Sopenharmony_ci	: "r" (p), "r" (val)
12962306a36Sopenharmony_ci	: "cc", "memory");
13062306a36Sopenharmony_ci
13162306a36Sopenharmony_ci	return prev;
13262306a36Sopenharmony_ci}
13362306a36Sopenharmony_ci
13462306a36Sopenharmony_cistatic __always_inline unsigned long
13562306a36Sopenharmony_ci__xchg_u16_relaxed(u16 *p, unsigned long val)
13662306a36Sopenharmony_ci{
13762306a36Sopenharmony_ci	unsigned long prev;
13862306a36Sopenharmony_ci
13962306a36Sopenharmony_ci	__asm__ __volatile__(
14062306a36Sopenharmony_ci"1:	lharx	%0,0,%2		# __xchg_u16_relaxed\n"
14162306a36Sopenharmony_ci"	sthcx.	%3,0,%2\n"
14262306a36Sopenharmony_ci"	bne-	1b"
14362306a36Sopenharmony_ci	: "=&r" (prev), "+m" (*p)
14462306a36Sopenharmony_ci	: "r" (p), "r" (val)
14562306a36Sopenharmony_ci	: "cc");
14662306a36Sopenharmony_ci
14762306a36Sopenharmony_ci	return prev;
14862306a36Sopenharmony_ci}
14962306a36Sopenharmony_ci#endif
15062306a36Sopenharmony_ci
15162306a36Sopenharmony_cistatic __always_inline unsigned long
15262306a36Sopenharmony_ci__xchg_u32_local(volatile void *p, unsigned long val)
15362306a36Sopenharmony_ci{
15462306a36Sopenharmony_ci	unsigned long prev;
15562306a36Sopenharmony_ci
15662306a36Sopenharmony_ci	__asm__ __volatile__(
15762306a36Sopenharmony_ci"1:	lwarx	%0,0,%2 \n"
15862306a36Sopenharmony_ci"	stwcx.	%3,0,%2 \n\
15962306a36Sopenharmony_ci	bne-	1b"
16062306a36Sopenharmony_ci	: "=&r" (prev), "+m" (*(volatile unsigned int *)p)
16162306a36Sopenharmony_ci	: "r" (p), "r" (val)
16262306a36Sopenharmony_ci	: "cc", "memory");
16362306a36Sopenharmony_ci
16462306a36Sopenharmony_ci	return prev;
16562306a36Sopenharmony_ci}
16662306a36Sopenharmony_ci
16762306a36Sopenharmony_cistatic __always_inline unsigned long
16862306a36Sopenharmony_ci__xchg_u32_relaxed(u32 *p, unsigned long val)
16962306a36Sopenharmony_ci{
17062306a36Sopenharmony_ci	unsigned long prev;
17162306a36Sopenharmony_ci
17262306a36Sopenharmony_ci	__asm__ __volatile__(
17362306a36Sopenharmony_ci"1:	lwarx	%0,0,%2\n"
17462306a36Sopenharmony_ci"	stwcx.	%3,0,%2\n"
17562306a36Sopenharmony_ci"	bne-	1b"
17662306a36Sopenharmony_ci	: "=&r" (prev), "+m" (*p)
17762306a36Sopenharmony_ci	: "r" (p), "r" (val)
17862306a36Sopenharmony_ci	: "cc");
17962306a36Sopenharmony_ci
18062306a36Sopenharmony_ci	return prev;
18162306a36Sopenharmony_ci}
18262306a36Sopenharmony_ci
18362306a36Sopenharmony_ci#ifdef CONFIG_PPC64
18462306a36Sopenharmony_cistatic __always_inline unsigned long
18562306a36Sopenharmony_ci__xchg_u64_local(volatile void *p, unsigned long val)
18662306a36Sopenharmony_ci{
18762306a36Sopenharmony_ci	unsigned long prev;
18862306a36Sopenharmony_ci
18962306a36Sopenharmony_ci	__asm__ __volatile__(
19062306a36Sopenharmony_ci"1:	ldarx	%0,0,%2 \n"
19162306a36Sopenharmony_ci"	stdcx.	%3,0,%2 \n\
19262306a36Sopenharmony_ci	bne-	1b"
19362306a36Sopenharmony_ci	: "=&r" (prev), "+m" (*(volatile unsigned long *)p)
19462306a36Sopenharmony_ci	: "r" (p), "r" (val)
19562306a36Sopenharmony_ci	: "cc", "memory");
19662306a36Sopenharmony_ci
19762306a36Sopenharmony_ci	return prev;
19862306a36Sopenharmony_ci}
19962306a36Sopenharmony_ci
20062306a36Sopenharmony_cistatic __always_inline unsigned long
20162306a36Sopenharmony_ci__xchg_u64_relaxed(u64 *p, unsigned long val)
20262306a36Sopenharmony_ci{
20362306a36Sopenharmony_ci	unsigned long prev;
20462306a36Sopenharmony_ci
20562306a36Sopenharmony_ci	__asm__ __volatile__(
20662306a36Sopenharmony_ci"1:	ldarx	%0,0,%2\n"
20762306a36Sopenharmony_ci"	stdcx.	%3,0,%2\n"
20862306a36Sopenharmony_ci"	bne-	1b"
20962306a36Sopenharmony_ci	: "=&r" (prev), "+m" (*p)
21062306a36Sopenharmony_ci	: "r" (p), "r" (val)
21162306a36Sopenharmony_ci	: "cc");
21262306a36Sopenharmony_ci
21362306a36Sopenharmony_ci	return prev;
21462306a36Sopenharmony_ci}
21562306a36Sopenharmony_ci#endif
21662306a36Sopenharmony_ci
21762306a36Sopenharmony_cistatic __always_inline unsigned long
21862306a36Sopenharmony_ci__xchg_local(void *ptr, unsigned long x, unsigned int size)
21962306a36Sopenharmony_ci{
22062306a36Sopenharmony_ci	switch (size) {
22162306a36Sopenharmony_ci	case 1:
22262306a36Sopenharmony_ci		return __xchg_u8_local(ptr, x);
22362306a36Sopenharmony_ci	case 2:
22462306a36Sopenharmony_ci		return __xchg_u16_local(ptr, x);
22562306a36Sopenharmony_ci	case 4:
22662306a36Sopenharmony_ci		return __xchg_u32_local(ptr, x);
22762306a36Sopenharmony_ci#ifdef CONFIG_PPC64
22862306a36Sopenharmony_ci	case 8:
22962306a36Sopenharmony_ci		return __xchg_u64_local(ptr, x);
23062306a36Sopenharmony_ci#endif
23162306a36Sopenharmony_ci	}
23262306a36Sopenharmony_ci	BUILD_BUG_ON_MSG(1, "Unsupported size for __xchg_local");
23362306a36Sopenharmony_ci	return x;
23462306a36Sopenharmony_ci}
23562306a36Sopenharmony_ci
23662306a36Sopenharmony_cistatic __always_inline unsigned long
23762306a36Sopenharmony_ci__xchg_relaxed(void *ptr, unsigned long x, unsigned int size)
23862306a36Sopenharmony_ci{
23962306a36Sopenharmony_ci	switch (size) {
24062306a36Sopenharmony_ci	case 1:
24162306a36Sopenharmony_ci		return __xchg_u8_relaxed(ptr, x);
24262306a36Sopenharmony_ci	case 2:
24362306a36Sopenharmony_ci		return __xchg_u16_relaxed(ptr, x);
24462306a36Sopenharmony_ci	case 4:
24562306a36Sopenharmony_ci		return __xchg_u32_relaxed(ptr, x);
24662306a36Sopenharmony_ci#ifdef CONFIG_PPC64
24762306a36Sopenharmony_ci	case 8:
24862306a36Sopenharmony_ci		return __xchg_u64_relaxed(ptr, x);
24962306a36Sopenharmony_ci#endif
25062306a36Sopenharmony_ci	}
25162306a36Sopenharmony_ci	BUILD_BUG_ON_MSG(1, "Unsupported size for __xchg_relaxed");
25262306a36Sopenharmony_ci	return x;
25362306a36Sopenharmony_ci}
25462306a36Sopenharmony_ci#define arch_xchg_local(ptr,x)						     \
25562306a36Sopenharmony_ci  ({									     \
25662306a36Sopenharmony_ci     __typeof__(*(ptr)) _x_ = (x);					     \
25762306a36Sopenharmony_ci     (__typeof__(*(ptr))) __xchg_local((ptr),				     \
25862306a36Sopenharmony_ci     		(unsigned long)_x_, sizeof(*(ptr))); 			     \
25962306a36Sopenharmony_ci  })
26062306a36Sopenharmony_ci
26162306a36Sopenharmony_ci#define arch_xchg_relaxed(ptr, x)					\
26262306a36Sopenharmony_ci({									\
26362306a36Sopenharmony_ci	__typeof__(*(ptr)) _x_ = (x);					\
26462306a36Sopenharmony_ci	(__typeof__(*(ptr))) __xchg_relaxed((ptr),			\
26562306a36Sopenharmony_ci			(unsigned long)_x_, sizeof(*(ptr)));		\
26662306a36Sopenharmony_ci})
26762306a36Sopenharmony_ci
26862306a36Sopenharmony_ci/*
26962306a36Sopenharmony_ci * Compare and exchange - if *p == old, set it to new,
27062306a36Sopenharmony_ci * and return the old value of *p.
27162306a36Sopenharmony_ci */
27262306a36Sopenharmony_ci#ifndef CONFIG_PPC_HAS_LBARX_LHARX
27362306a36Sopenharmony_ciCMPXCHG_GEN(u8, , PPC_ATOMIC_ENTRY_BARRIER, PPC_ATOMIC_EXIT_BARRIER, "memory");
27462306a36Sopenharmony_ciCMPXCHG_GEN(u8, _local, , , "memory");
27562306a36Sopenharmony_ciCMPXCHG_GEN(u8, _acquire, , PPC_ACQUIRE_BARRIER, "memory");
27662306a36Sopenharmony_ciCMPXCHG_GEN(u8, _relaxed, , , "cc");
27762306a36Sopenharmony_ciCMPXCHG_GEN(u16, , PPC_ATOMIC_ENTRY_BARRIER, PPC_ATOMIC_EXIT_BARRIER, "memory");
27862306a36Sopenharmony_ciCMPXCHG_GEN(u16, _local, , , "memory");
27962306a36Sopenharmony_ciCMPXCHG_GEN(u16, _acquire, , PPC_ACQUIRE_BARRIER, "memory");
28062306a36Sopenharmony_ciCMPXCHG_GEN(u16, _relaxed, , , "cc");
28162306a36Sopenharmony_ci#else
28262306a36Sopenharmony_cistatic __always_inline unsigned long
28362306a36Sopenharmony_ci__cmpxchg_u8(volatile unsigned char *p, unsigned long old, unsigned long new)
28462306a36Sopenharmony_ci{
28562306a36Sopenharmony_ci	unsigned int prev;
28662306a36Sopenharmony_ci
28762306a36Sopenharmony_ci	__asm__ __volatile__ (
28862306a36Sopenharmony_ci	PPC_ATOMIC_ENTRY_BARRIER
28962306a36Sopenharmony_ci"1:	lbarx	%0,0,%2		# __cmpxchg_u8\n"
29062306a36Sopenharmony_ci"	cmpw	0,%0,%3\n"
29162306a36Sopenharmony_ci"	bne-	2f\n"
29262306a36Sopenharmony_ci"	stbcx.	%4,0,%2\n"
29362306a36Sopenharmony_ci"	bne-	1b"
29462306a36Sopenharmony_ci	PPC_ATOMIC_EXIT_BARRIER
29562306a36Sopenharmony_ci	"\n\
29662306a36Sopenharmony_ci2:"
29762306a36Sopenharmony_ci	: "=&r" (prev), "+m" (*p)
29862306a36Sopenharmony_ci	: "r" (p), "r" (old), "r" (new)
29962306a36Sopenharmony_ci	: "cc", "memory");
30062306a36Sopenharmony_ci
30162306a36Sopenharmony_ci	return prev;
30262306a36Sopenharmony_ci}
30362306a36Sopenharmony_ci
30462306a36Sopenharmony_cistatic __always_inline unsigned long
30562306a36Sopenharmony_ci__cmpxchg_u8_local(volatile unsigned char *p, unsigned long old,
30662306a36Sopenharmony_ci			unsigned long new)
30762306a36Sopenharmony_ci{
30862306a36Sopenharmony_ci	unsigned int prev;
30962306a36Sopenharmony_ci
31062306a36Sopenharmony_ci	__asm__ __volatile__ (
31162306a36Sopenharmony_ci"1:	lbarx	%0,0,%2		# __cmpxchg_u8_local\n"
31262306a36Sopenharmony_ci"	cmpw	0,%0,%3\n"
31362306a36Sopenharmony_ci"	bne-	2f\n"
31462306a36Sopenharmony_ci"	stbcx.	%4,0,%2\n"
31562306a36Sopenharmony_ci"	bne-	1b\n"
31662306a36Sopenharmony_ci"2:"
31762306a36Sopenharmony_ci	: "=&r" (prev), "+m" (*p)
31862306a36Sopenharmony_ci	: "r" (p), "r" (old), "r" (new)
31962306a36Sopenharmony_ci	: "cc", "memory");
32062306a36Sopenharmony_ci
32162306a36Sopenharmony_ci	return prev;
32262306a36Sopenharmony_ci}
32362306a36Sopenharmony_ci
32462306a36Sopenharmony_cistatic __always_inline unsigned long
32562306a36Sopenharmony_ci__cmpxchg_u8_relaxed(u8 *p, unsigned long old, unsigned long new)
32662306a36Sopenharmony_ci{
32762306a36Sopenharmony_ci	unsigned long prev;
32862306a36Sopenharmony_ci
32962306a36Sopenharmony_ci	__asm__ __volatile__ (
33062306a36Sopenharmony_ci"1:	lbarx	%0,0,%2		# __cmpxchg_u8_relaxed\n"
33162306a36Sopenharmony_ci"	cmpw	0,%0,%3\n"
33262306a36Sopenharmony_ci"	bne-	2f\n"
33362306a36Sopenharmony_ci"	stbcx.	%4,0,%2\n"
33462306a36Sopenharmony_ci"	bne-	1b\n"
33562306a36Sopenharmony_ci"2:"
33662306a36Sopenharmony_ci	: "=&r" (prev), "+m" (*p)
33762306a36Sopenharmony_ci	: "r" (p), "r" (old), "r" (new)
33862306a36Sopenharmony_ci	: "cc");
33962306a36Sopenharmony_ci
34062306a36Sopenharmony_ci	return prev;
34162306a36Sopenharmony_ci}
34262306a36Sopenharmony_ci
34362306a36Sopenharmony_cistatic __always_inline unsigned long
34462306a36Sopenharmony_ci__cmpxchg_u8_acquire(u8 *p, unsigned long old, unsigned long new)
34562306a36Sopenharmony_ci{
34662306a36Sopenharmony_ci	unsigned long prev;
34762306a36Sopenharmony_ci
34862306a36Sopenharmony_ci	__asm__ __volatile__ (
34962306a36Sopenharmony_ci"1:	lbarx	%0,0,%2		# __cmpxchg_u8_acquire\n"
35062306a36Sopenharmony_ci"	cmpw	0,%0,%3\n"
35162306a36Sopenharmony_ci"	bne-	2f\n"
35262306a36Sopenharmony_ci"	stbcx.	%4,0,%2\n"
35362306a36Sopenharmony_ci"	bne-	1b\n"
35462306a36Sopenharmony_ci	PPC_ACQUIRE_BARRIER
35562306a36Sopenharmony_ci"2:"
35662306a36Sopenharmony_ci	: "=&r" (prev), "+m" (*p)
35762306a36Sopenharmony_ci	: "r" (p), "r" (old), "r" (new)
35862306a36Sopenharmony_ci	: "cc", "memory");
35962306a36Sopenharmony_ci
36062306a36Sopenharmony_ci	return prev;
36162306a36Sopenharmony_ci}
36262306a36Sopenharmony_ci
36362306a36Sopenharmony_cistatic __always_inline unsigned long
36462306a36Sopenharmony_ci__cmpxchg_u16(volatile unsigned short *p, unsigned long old, unsigned long new)
36562306a36Sopenharmony_ci{
36662306a36Sopenharmony_ci	unsigned int prev;
36762306a36Sopenharmony_ci
36862306a36Sopenharmony_ci	__asm__ __volatile__ (
36962306a36Sopenharmony_ci	PPC_ATOMIC_ENTRY_BARRIER
37062306a36Sopenharmony_ci"1:	lharx	%0,0,%2		# __cmpxchg_u16\n"
37162306a36Sopenharmony_ci"	cmpw	0,%0,%3\n"
37262306a36Sopenharmony_ci"	bne-	2f\n"
37362306a36Sopenharmony_ci"	sthcx.	%4,0,%2\n"
37462306a36Sopenharmony_ci"	bne-	1b\n"
37562306a36Sopenharmony_ci	PPC_ATOMIC_EXIT_BARRIER
37662306a36Sopenharmony_ci"2:"
37762306a36Sopenharmony_ci	: "=&r" (prev), "+m" (*p)
37862306a36Sopenharmony_ci	: "r" (p), "r" (old), "r" (new)
37962306a36Sopenharmony_ci	: "cc", "memory");
38062306a36Sopenharmony_ci
38162306a36Sopenharmony_ci	return prev;
38262306a36Sopenharmony_ci}
38362306a36Sopenharmony_ci
38462306a36Sopenharmony_cistatic __always_inline unsigned long
38562306a36Sopenharmony_ci__cmpxchg_u16_local(volatile unsigned short *p, unsigned long old,
38662306a36Sopenharmony_ci			unsigned long new)
38762306a36Sopenharmony_ci{
38862306a36Sopenharmony_ci	unsigned int prev;
38962306a36Sopenharmony_ci
39062306a36Sopenharmony_ci	__asm__ __volatile__ (
39162306a36Sopenharmony_ci"1:	lharx	%0,0,%2		# __cmpxchg_u16_local\n"
39262306a36Sopenharmony_ci"	cmpw	0,%0,%3\n"
39362306a36Sopenharmony_ci"	bne-	2f\n"
39462306a36Sopenharmony_ci"	sthcx.	%4,0,%2\n"
39562306a36Sopenharmony_ci"	bne-	1b"
39662306a36Sopenharmony_ci"2:"
39762306a36Sopenharmony_ci	: "=&r" (prev), "+m" (*p)
39862306a36Sopenharmony_ci	: "r" (p), "r" (old), "r" (new)
39962306a36Sopenharmony_ci	: "cc", "memory");
40062306a36Sopenharmony_ci
40162306a36Sopenharmony_ci	return prev;
40262306a36Sopenharmony_ci}
40362306a36Sopenharmony_ci
40462306a36Sopenharmony_cistatic __always_inline unsigned long
40562306a36Sopenharmony_ci__cmpxchg_u16_relaxed(u16 *p, unsigned long old, unsigned long new)
40662306a36Sopenharmony_ci{
40762306a36Sopenharmony_ci	unsigned long prev;
40862306a36Sopenharmony_ci
40962306a36Sopenharmony_ci	__asm__ __volatile__ (
41062306a36Sopenharmony_ci"1:	lharx	%0,0,%2		# __cmpxchg_u16_relaxed\n"
41162306a36Sopenharmony_ci"	cmpw	0,%0,%3\n"
41262306a36Sopenharmony_ci"	bne-	2f\n"
41362306a36Sopenharmony_ci"	sthcx.	%4,0,%2\n"
41462306a36Sopenharmony_ci"	bne-	1b\n"
41562306a36Sopenharmony_ci"2:"
41662306a36Sopenharmony_ci	: "=&r" (prev), "+m" (*p)
41762306a36Sopenharmony_ci	: "r" (p), "r" (old), "r" (new)
41862306a36Sopenharmony_ci	: "cc");
41962306a36Sopenharmony_ci
42062306a36Sopenharmony_ci	return prev;
42162306a36Sopenharmony_ci}
42262306a36Sopenharmony_ci
42362306a36Sopenharmony_cistatic __always_inline unsigned long
42462306a36Sopenharmony_ci__cmpxchg_u16_acquire(u16 *p, unsigned long old, unsigned long new)
42562306a36Sopenharmony_ci{
42662306a36Sopenharmony_ci	unsigned long prev;
42762306a36Sopenharmony_ci
42862306a36Sopenharmony_ci	__asm__ __volatile__ (
42962306a36Sopenharmony_ci"1:	lharx	%0,0,%2		# __cmpxchg_u16_acquire\n"
43062306a36Sopenharmony_ci"	cmpw	0,%0,%3\n"
43162306a36Sopenharmony_ci"	bne-	2f\n"
43262306a36Sopenharmony_ci"	sthcx.	%4,0,%2\n"
43362306a36Sopenharmony_ci"	bne-	1b\n"
43462306a36Sopenharmony_ci	PPC_ACQUIRE_BARRIER
43562306a36Sopenharmony_ci"2:"
43662306a36Sopenharmony_ci	: "=&r" (prev), "+m" (*p)
43762306a36Sopenharmony_ci	: "r" (p), "r" (old), "r" (new)
43862306a36Sopenharmony_ci	: "cc", "memory");
43962306a36Sopenharmony_ci
44062306a36Sopenharmony_ci	return prev;
44162306a36Sopenharmony_ci}
44262306a36Sopenharmony_ci#endif
44362306a36Sopenharmony_ci
44462306a36Sopenharmony_cistatic __always_inline unsigned long
44562306a36Sopenharmony_ci__cmpxchg_u32(volatile unsigned int *p, unsigned long old, unsigned long new)
44662306a36Sopenharmony_ci{
44762306a36Sopenharmony_ci	unsigned int prev;
44862306a36Sopenharmony_ci
44962306a36Sopenharmony_ci	__asm__ __volatile__ (
45062306a36Sopenharmony_ci	PPC_ATOMIC_ENTRY_BARRIER
45162306a36Sopenharmony_ci"1:	lwarx	%0,0,%2		# __cmpxchg_u32\n\
45262306a36Sopenharmony_ci	cmpw	0,%0,%3\n\
45362306a36Sopenharmony_ci	bne-	2f\n"
45462306a36Sopenharmony_ci"	stwcx.	%4,0,%2\n\
45562306a36Sopenharmony_ci	bne-	1b"
45662306a36Sopenharmony_ci	PPC_ATOMIC_EXIT_BARRIER
45762306a36Sopenharmony_ci	"\n\
45862306a36Sopenharmony_ci2:"
45962306a36Sopenharmony_ci	: "=&r" (prev), "+m" (*p)
46062306a36Sopenharmony_ci	: "r" (p), "r" (old), "r" (new)
46162306a36Sopenharmony_ci	: "cc", "memory");
46262306a36Sopenharmony_ci
46362306a36Sopenharmony_ci	return prev;
46462306a36Sopenharmony_ci}
46562306a36Sopenharmony_ci
46662306a36Sopenharmony_cistatic __always_inline unsigned long
46762306a36Sopenharmony_ci__cmpxchg_u32_local(volatile unsigned int *p, unsigned long old,
46862306a36Sopenharmony_ci			unsigned long new)
46962306a36Sopenharmony_ci{
47062306a36Sopenharmony_ci	unsigned int prev;
47162306a36Sopenharmony_ci
47262306a36Sopenharmony_ci	__asm__ __volatile__ (
47362306a36Sopenharmony_ci"1:	lwarx	%0,0,%2		# __cmpxchg_u32\n\
47462306a36Sopenharmony_ci	cmpw	0,%0,%3\n\
47562306a36Sopenharmony_ci	bne-	2f\n"
47662306a36Sopenharmony_ci"	stwcx.	%4,0,%2\n\
47762306a36Sopenharmony_ci	bne-	1b"
47862306a36Sopenharmony_ci	"\n\
47962306a36Sopenharmony_ci2:"
48062306a36Sopenharmony_ci	: "=&r" (prev), "+m" (*p)
48162306a36Sopenharmony_ci	: "r" (p), "r" (old), "r" (new)
48262306a36Sopenharmony_ci	: "cc", "memory");
48362306a36Sopenharmony_ci
48462306a36Sopenharmony_ci	return prev;
48562306a36Sopenharmony_ci}
48662306a36Sopenharmony_ci
48762306a36Sopenharmony_cistatic __always_inline unsigned long
48862306a36Sopenharmony_ci__cmpxchg_u32_relaxed(u32 *p, unsigned long old, unsigned long new)
48962306a36Sopenharmony_ci{
49062306a36Sopenharmony_ci	unsigned long prev;
49162306a36Sopenharmony_ci
49262306a36Sopenharmony_ci	__asm__ __volatile__ (
49362306a36Sopenharmony_ci"1:	lwarx	%0,0,%2		# __cmpxchg_u32_relaxed\n"
49462306a36Sopenharmony_ci"	cmpw	0,%0,%3\n"
49562306a36Sopenharmony_ci"	bne-	2f\n"
49662306a36Sopenharmony_ci"	stwcx.	%4,0,%2\n"
49762306a36Sopenharmony_ci"	bne-	1b\n"
49862306a36Sopenharmony_ci"2:"
49962306a36Sopenharmony_ci	: "=&r" (prev), "+m" (*p)
50062306a36Sopenharmony_ci	: "r" (p), "r" (old), "r" (new)
50162306a36Sopenharmony_ci	: "cc");
50262306a36Sopenharmony_ci
50362306a36Sopenharmony_ci	return prev;
50462306a36Sopenharmony_ci}
50562306a36Sopenharmony_ci
50662306a36Sopenharmony_ci/*
50762306a36Sopenharmony_ci * cmpxchg family don't have order guarantee if cmp part fails, therefore we
50862306a36Sopenharmony_ci * can avoid superfluous barriers if we use assembly code to implement
50962306a36Sopenharmony_ci * cmpxchg() and cmpxchg_acquire(), however we don't do the similar for
51062306a36Sopenharmony_ci * cmpxchg_release() because that will result in putting a barrier in the
51162306a36Sopenharmony_ci * middle of a ll/sc loop, which is probably a bad idea. For example, this
51262306a36Sopenharmony_ci * might cause the conditional store more likely to fail.
51362306a36Sopenharmony_ci */
51462306a36Sopenharmony_cistatic __always_inline unsigned long
51562306a36Sopenharmony_ci__cmpxchg_u32_acquire(u32 *p, unsigned long old, unsigned long new)
51662306a36Sopenharmony_ci{
51762306a36Sopenharmony_ci	unsigned long prev;
51862306a36Sopenharmony_ci
51962306a36Sopenharmony_ci	__asm__ __volatile__ (
52062306a36Sopenharmony_ci"1:	lwarx	%0,0,%2		# __cmpxchg_u32_acquire\n"
52162306a36Sopenharmony_ci"	cmpw	0,%0,%3\n"
52262306a36Sopenharmony_ci"	bne-	2f\n"
52362306a36Sopenharmony_ci"	stwcx.	%4,0,%2\n"
52462306a36Sopenharmony_ci"	bne-	1b\n"
52562306a36Sopenharmony_ci	PPC_ACQUIRE_BARRIER
52662306a36Sopenharmony_ci	"\n"
52762306a36Sopenharmony_ci"2:"
52862306a36Sopenharmony_ci	: "=&r" (prev), "+m" (*p)
52962306a36Sopenharmony_ci	: "r" (p), "r" (old), "r" (new)
53062306a36Sopenharmony_ci	: "cc", "memory");
53162306a36Sopenharmony_ci
53262306a36Sopenharmony_ci	return prev;
53362306a36Sopenharmony_ci}
53462306a36Sopenharmony_ci
53562306a36Sopenharmony_ci#ifdef CONFIG_PPC64
53662306a36Sopenharmony_cistatic __always_inline unsigned long
53762306a36Sopenharmony_ci__cmpxchg_u64(volatile unsigned long *p, unsigned long old, unsigned long new)
53862306a36Sopenharmony_ci{
53962306a36Sopenharmony_ci	unsigned long prev;
54062306a36Sopenharmony_ci
54162306a36Sopenharmony_ci	__asm__ __volatile__ (
54262306a36Sopenharmony_ci	PPC_ATOMIC_ENTRY_BARRIER
54362306a36Sopenharmony_ci"1:	ldarx	%0,0,%2		# __cmpxchg_u64\n\
54462306a36Sopenharmony_ci	cmpd	0,%0,%3\n\
54562306a36Sopenharmony_ci	bne-	2f\n\
54662306a36Sopenharmony_ci	stdcx.	%4,0,%2\n\
54762306a36Sopenharmony_ci	bne-	1b"
54862306a36Sopenharmony_ci	PPC_ATOMIC_EXIT_BARRIER
54962306a36Sopenharmony_ci	"\n\
55062306a36Sopenharmony_ci2:"
55162306a36Sopenharmony_ci	: "=&r" (prev), "+m" (*p)
55262306a36Sopenharmony_ci	: "r" (p), "r" (old), "r" (new)
55362306a36Sopenharmony_ci	: "cc", "memory");
55462306a36Sopenharmony_ci
55562306a36Sopenharmony_ci	return prev;
55662306a36Sopenharmony_ci}
55762306a36Sopenharmony_ci
55862306a36Sopenharmony_cistatic __always_inline unsigned long
55962306a36Sopenharmony_ci__cmpxchg_u64_local(volatile unsigned long *p, unsigned long old,
56062306a36Sopenharmony_ci			unsigned long new)
56162306a36Sopenharmony_ci{
56262306a36Sopenharmony_ci	unsigned long prev;
56362306a36Sopenharmony_ci
56462306a36Sopenharmony_ci	__asm__ __volatile__ (
56562306a36Sopenharmony_ci"1:	ldarx	%0,0,%2		# __cmpxchg_u64\n\
56662306a36Sopenharmony_ci	cmpd	0,%0,%3\n\
56762306a36Sopenharmony_ci	bne-	2f\n\
56862306a36Sopenharmony_ci	stdcx.	%4,0,%2\n\
56962306a36Sopenharmony_ci	bne-	1b"
57062306a36Sopenharmony_ci	"\n\
57162306a36Sopenharmony_ci2:"
57262306a36Sopenharmony_ci	: "=&r" (prev), "+m" (*p)
57362306a36Sopenharmony_ci	: "r" (p), "r" (old), "r" (new)
57462306a36Sopenharmony_ci	: "cc", "memory");
57562306a36Sopenharmony_ci
57662306a36Sopenharmony_ci	return prev;
57762306a36Sopenharmony_ci}
57862306a36Sopenharmony_ci
57962306a36Sopenharmony_cistatic __always_inline unsigned long
58062306a36Sopenharmony_ci__cmpxchg_u64_relaxed(u64 *p, unsigned long old, unsigned long new)
58162306a36Sopenharmony_ci{
58262306a36Sopenharmony_ci	unsigned long prev;
58362306a36Sopenharmony_ci
58462306a36Sopenharmony_ci	__asm__ __volatile__ (
58562306a36Sopenharmony_ci"1:	ldarx	%0,0,%2		# __cmpxchg_u64_relaxed\n"
58662306a36Sopenharmony_ci"	cmpd	0,%0,%3\n"
58762306a36Sopenharmony_ci"	bne-	2f\n"
58862306a36Sopenharmony_ci"	stdcx.	%4,0,%2\n"
58962306a36Sopenharmony_ci"	bne-	1b\n"
59062306a36Sopenharmony_ci"2:"
59162306a36Sopenharmony_ci	: "=&r" (prev), "+m" (*p)
59262306a36Sopenharmony_ci	: "r" (p), "r" (old), "r" (new)
59362306a36Sopenharmony_ci	: "cc");
59462306a36Sopenharmony_ci
59562306a36Sopenharmony_ci	return prev;
59662306a36Sopenharmony_ci}
59762306a36Sopenharmony_ci
59862306a36Sopenharmony_cistatic __always_inline unsigned long
59962306a36Sopenharmony_ci__cmpxchg_u64_acquire(u64 *p, unsigned long old, unsigned long new)
60062306a36Sopenharmony_ci{
60162306a36Sopenharmony_ci	unsigned long prev;
60262306a36Sopenharmony_ci
60362306a36Sopenharmony_ci	__asm__ __volatile__ (
60462306a36Sopenharmony_ci"1:	ldarx	%0,0,%2		# __cmpxchg_u64_acquire\n"
60562306a36Sopenharmony_ci"	cmpd	0,%0,%3\n"
60662306a36Sopenharmony_ci"	bne-	2f\n"
60762306a36Sopenharmony_ci"	stdcx.	%4,0,%2\n"
60862306a36Sopenharmony_ci"	bne-	1b\n"
60962306a36Sopenharmony_ci	PPC_ACQUIRE_BARRIER
61062306a36Sopenharmony_ci	"\n"
61162306a36Sopenharmony_ci"2:"
61262306a36Sopenharmony_ci	: "=&r" (prev), "+m" (*p)
61362306a36Sopenharmony_ci	: "r" (p), "r" (old), "r" (new)
61462306a36Sopenharmony_ci	: "cc", "memory");
61562306a36Sopenharmony_ci
61662306a36Sopenharmony_ci	return prev;
61762306a36Sopenharmony_ci}
61862306a36Sopenharmony_ci#endif
61962306a36Sopenharmony_ci
62062306a36Sopenharmony_cistatic __always_inline unsigned long
62162306a36Sopenharmony_ci__cmpxchg(volatile void *ptr, unsigned long old, unsigned long new,
62262306a36Sopenharmony_ci	  unsigned int size)
62362306a36Sopenharmony_ci{
62462306a36Sopenharmony_ci	switch (size) {
62562306a36Sopenharmony_ci	case 1:
62662306a36Sopenharmony_ci		return __cmpxchg_u8(ptr, old, new);
62762306a36Sopenharmony_ci	case 2:
62862306a36Sopenharmony_ci		return __cmpxchg_u16(ptr, old, new);
62962306a36Sopenharmony_ci	case 4:
63062306a36Sopenharmony_ci		return __cmpxchg_u32(ptr, old, new);
63162306a36Sopenharmony_ci#ifdef CONFIG_PPC64
63262306a36Sopenharmony_ci	case 8:
63362306a36Sopenharmony_ci		return __cmpxchg_u64(ptr, old, new);
63462306a36Sopenharmony_ci#endif
63562306a36Sopenharmony_ci	}
63662306a36Sopenharmony_ci	BUILD_BUG_ON_MSG(1, "Unsupported size for __cmpxchg");
63762306a36Sopenharmony_ci	return old;
63862306a36Sopenharmony_ci}
63962306a36Sopenharmony_ci
64062306a36Sopenharmony_cistatic __always_inline unsigned long
64162306a36Sopenharmony_ci__cmpxchg_local(void *ptr, unsigned long old, unsigned long new,
64262306a36Sopenharmony_ci	  unsigned int size)
64362306a36Sopenharmony_ci{
64462306a36Sopenharmony_ci	switch (size) {
64562306a36Sopenharmony_ci	case 1:
64662306a36Sopenharmony_ci		return __cmpxchg_u8_local(ptr, old, new);
64762306a36Sopenharmony_ci	case 2:
64862306a36Sopenharmony_ci		return __cmpxchg_u16_local(ptr, old, new);
64962306a36Sopenharmony_ci	case 4:
65062306a36Sopenharmony_ci		return __cmpxchg_u32_local(ptr, old, new);
65162306a36Sopenharmony_ci#ifdef CONFIG_PPC64
65262306a36Sopenharmony_ci	case 8:
65362306a36Sopenharmony_ci		return __cmpxchg_u64_local(ptr, old, new);
65462306a36Sopenharmony_ci#endif
65562306a36Sopenharmony_ci	}
65662306a36Sopenharmony_ci	BUILD_BUG_ON_MSG(1, "Unsupported size for __cmpxchg_local");
65762306a36Sopenharmony_ci	return old;
65862306a36Sopenharmony_ci}
65962306a36Sopenharmony_ci
66062306a36Sopenharmony_cistatic __always_inline unsigned long
66162306a36Sopenharmony_ci__cmpxchg_relaxed(void *ptr, unsigned long old, unsigned long new,
66262306a36Sopenharmony_ci		  unsigned int size)
66362306a36Sopenharmony_ci{
66462306a36Sopenharmony_ci	switch (size) {
66562306a36Sopenharmony_ci	case 1:
66662306a36Sopenharmony_ci		return __cmpxchg_u8_relaxed(ptr, old, new);
66762306a36Sopenharmony_ci	case 2:
66862306a36Sopenharmony_ci		return __cmpxchg_u16_relaxed(ptr, old, new);
66962306a36Sopenharmony_ci	case 4:
67062306a36Sopenharmony_ci		return __cmpxchg_u32_relaxed(ptr, old, new);
67162306a36Sopenharmony_ci#ifdef CONFIG_PPC64
67262306a36Sopenharmony_ci	case 8:
67362306a36Sopenharmony_ci		return __cmpxchg_u64_relaxed(ptr, old, new);
67462306a36Sopenharmony_ci#endif
67562306a36Sopenharmony_ci	}
67662306a36Sopenharmony_ci	BUILD_BUG_ON_MSG(1, "Unsupported size for __cmpxchg_relaxed");
67762306a36Sopenharmony_ci	return old;
67862306a36Sopenharmony_ci}
67962306a36Sopenharmony_ci
68062306a36Sopenharmony_cistatic __always_inline unsigned long
68162306a36Sopenharmony_ci__cmpxchg_acquire(void *ptr, unsigned long old, unsigned long new,
68262306a36Sopenharmony_ci		  unsigned int size)
68362306a36Sopenharmony_ci{
68462306a36Sopenharmony_ci	switch (size) {
68562306a36Sopenharmony_ci	case 1:
68662306a36Sopenharmony_ci		return __cmpxchg_u8_acquire(ptr, old, new);
68762306a36Sopenharmony_ci	case 2:
68862306a36Sopenharmony_ci		return __cmpxchg_u16_acquire(ptr, old, new);
68962306a36Sopenharmony_ci	case 4:
69062306a36Sopenharmony_ci		return __cmpxchg_u32_acquire(ptr, old, new);
69162306a36Sopenharmony_ci#ifdef CONFIG_PPC64
69262306a36Sopenharmony_ci	case 8:
69362306a36Sopenharmony_ci		return __cmpxchg_u64_acquire(ptr, old, new);
69462306a36Sopenharmony_ci#endif
69562306a36Sopenharmony_ci	}
69662306a36Sopenharmony_ci	BUILD_BUG_ON_MSG(1, "Unsupported size for __cmpxchg_acquire");
69762306a36Sopenharmony_ci	return old;
69862306a36Sopenharmony_ci}
69962306a36Sopenharmony_ci#define arch_cmpxchg(ptr, o, n)						 \
70062306a36Sopenharmony_ci  ({									 \
70162306a36Sopenharmony_ci     __typeof__(*(ptr)) _o_ = (o);					 \
70262306a36Sopenharmony_ci     __typeof__(*(ptr)) _n_ = (n);					 \
70362306a36Sopenharmony_ci     (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_,		 \
70462306a36Sopenharmony_ci				    (unsigned long)_n_, sizeof(*(ptr))); \
70562306a36Sopenharmony_ci  })
70662306a36Sopenharmony_ci
70762306a36Sopenharmony_ci
70862306a36Sopenharmony_ci#define arch_cmpxchg_local(ptr, o, n)					 \
70962306a36Sopenharmony_ci  ({									 \
71062306a36Sopenharmony_ci     __typeof__(*(ptr)) _o_ = (o);					 \
71162306a36Sopenharmony_ci     __typeof__(*(ptr)) _n_ = (n);					 \
71262306a36Sopenharmony_ci     (__typeof__(*(ptr))) __cmpxchg_local((ptr), (unsigned long)_o_,	 \
71362306a36Sopenharmony_ci				    (unsigned long)_n_, sizeof(*(ptr))); \
71462306a36Sopenharmony_ci  })
71562306a36Sopenharmony_ci
71662306a36Sopenharmony_ci#define arch_cmpxchg_relaxed(ptr, o, n)					\
71762306a36Sopenharmony_ci({									\
71862306a36Sopenharmony_ci	__typeof__(*(ptr)) _o_ = (o);					\
71962306a36Sopenharmony_ci	__typeof__(*(ptr)) _n_ = (n);					\
72062306a36Sopenharmony_ci	(__typeof__(*(ptr))) __cmpxchg_relaxed((ptr),			\
72162306a36Sopenharmony_ci			(unsigned long)_o_, (unsigned long)_n_,		\
72262306a36Sopenharmony_ci			sizeof(*(ptr)));				\
72362306a36Sopenharmony_ci})
72462306a36Sopenharmony_ci
72562306a36Sopenharmony_ci#define arch_cmpxchg_acquire(ptr, o, n)					\
72662306a36Sopenharmony_ci({									\
72762306a36Sopenharmony_ci	__typeof__(*(ptr)) _o_ = (o);					\
72862306a36Sopenharmony_ci	__typeof__(*(ptr)) _n_ = (n);					\
72962306a36Sopenharmony_ci	(__typeof__(*(ptr))) __cmpxchg_acquire((ptr),			\
73062306a36Sopenharmony_ci			(unsigned long)_o_, (unsigned long)_n_,		\
73162306a36Sopenharmony_ci			sizeof(*(ptr)));				\
73262306a36Sopenharmony_ci})
73362306a36Sopenharmony_ci#ifdef CONFIG_PPC64
73462306a36Sopenharmony_ci#define arch_cmpxchg64(ptr, o, n)					\
73562306a36Sopenharmony_ci  ({									\
73662306a36Sopenharmony_ci	BUILD_BUG_ON(sizeof(*(ptr)) != 8);				\
73762306a36Sopenharmony_ci	arch_cmpxchg((ptr), (o), (n));					\
73862306a36Sopenharmony_ci  })
73962306a36Sopenharmony_ci#define arch_cmpxchg64_local(ptr, o, n)					\
74062306a36Sopenharmony_ci  ({									\
74162306a36Sopenharmony_ci	BUILD_BUG_ON(sizeof(*(ptr)) != 8);				\
74262306a36Sopenharmony_ci	arch_cmpxchg_local((ptr), (o), (n));				\
74362306a36Sopenharmony_ci  })
74462306a36Sopenharmony_ci#define arch_cmpxchg64_relaxed(ptr, o, n)				\
74562306a36Sopenharmony_ci({									\
74662306a36Sopenharmony_ci	BUILD_BUG_ON(sizeof(*(ptr)) != 8);				\
74762306a36Sopenharmony_ci	arch_cmpxchg_relaxed((ptr), (o), (n));				\
74862306a36Sopenharmony_ci})
74962306a36Sopenharmony_ci#define arch_cmpxchg64_acquire(ptr, o, n)				\
75062306a36Sopenharmony_ci({									\
75162306a36Sopenharmony_ci	BUILD_BUG_ON(sizeof(*(ptr)) != 8);				\
75262306a36Sopenharmony_ci	arch_cmpxchg_acquire((ptr), (o), (n));				\
75362306a36Sopenharmony_ci})
75462306a36Sopenharmony_ci#else
75562306a36Sopenharmony_ci#include <asm-generic/cmpxchg-local.h>
75662306a36Sopenharmony_ci#define arch_cmpxchg64_local(ptr, o, n) __generic_cmpxchg64_local((ptr), (o), (n))
75762306a36Sopenharmony_ci#endif
75862306a36Sopenharmony_ci
75962306a36Sopenharmony_ci#endif /* __KERNEL__ */
76062306a36Sopenharmony_ci#endif /* _ASM_POWERPC_CMPXCHG_H_ */
761