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