Use the new cmpxchg_emu_u8() to emulate one-byte cmpxchg() on arc. [ paulmck: Drop two-byte support per Arnd Bergmann feedback. ] Signed-off-by: Paul E. McKenney <paulmck@xxxxxxxxxx> Cc: Vineet Gupta <vgupta@xxxxxxxxxx> Cc: Andi Shyti <andi.shyti@xxxxxxxxxxxxxxx> Cc: Andrzej Hajda <andrzej.hajda@xxxxxxxxx> Cc: Arnd Bergmann <arnd@xxxxxxxx> Cc: Palmer Dabbelt <palmer@xxxxxxxxxxxx> Cc: Arnd Bergmann <arnd@xxxxxxxx> Cc: <linux-snps-arc@xxxxxxxxxxxxxxxxxxx> --- arch/arc/Kconfig | 1 + arch/arc/include/asm/cmpxchg.h | 32 +++++++++++++++++++++++--------- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig index 99d2845f3feb9..5bf6137f0fd47 100644 --- a/arch/arc/Kconfig +++ b/arch/arc/Kconfig @@ -14,6 +14,7 @@ config ARC select ARCH_HAS_SETUP_DMA_OPS select ARCH_HAS_SYNC_DMA_FOR_CPU select ARCH_HAS_SYNC_DMA_FOR_DEVICE + select ARCH_NEED_CMPXCHG_1_EMU select ARCH_SUPPORTS_ATOMIC_RMW if ARC_HAS_LLSC select ARCH_32BIT_OFF_T select BUILDTIME_TABLE_SORT diff --git a/arch/arc/include/asm/cmpxchg.h b/arch/arc/include/asm/cmpxchg.h index e138fde067dea..c3833e18389f4 100644 --- a/arch/arc/include/asm/cmpxchg.h +++ b/arch/arc/include/asm/cmpxchg.h @@ -46,6 +46,9 @@ __typeof__(*(ptr)) _prev_; \ \ switch(sizeof((_p_))) { \ + case 1: \ + _prev_ = cmpxchg_emu_u8((volatile u8 *)_p_, _o_, _n_); \ + break; \ case 4: \ _prev_ = __cmpxchg(_p_, _o_, _n_); \ break; \ @@ -65,16 +68,27 @@ __typeof__(*(ptr)) _prev_; \ unsigned long __flags; \ \ - BUILD_BUG_ON(sizeof(_p_) != 4); \ + switch(sizeof((_p_))) { \ + case 1: \ + __flags = cmpxchg_emu_u8((volatile u8 *)_p_, _o_, _n_); \ + _prev_ = (__typeof__(*(ptr)))__flags; \ + break; \ + break; \ + case 4: \ + /* \ + * spin lock/unlock provide the needed smp_mb() \ + * before/after \ + */ \ + atomic_ops_lock(__flags); \ + _prev_ = *_p_; \ + if (_prev_ == _o_) \ + *_p_ = _n_; \ + atomic_ops_unlock(__flags); \ + break; \ + default: \ + BUILD_BUG(); \ + } \ \ - /* \ - * spin lock/unlock provide the needed smp_mb() before/after \ - */ \ - atomic_ops_lock(__flags); \ - _prev_ = *_p_; \ - if (_prev_ == _o_) \ - *_p_ = _n_; \ - atomic_ops_unlock(__flags); \ _prev_; \ }) -- 2.40.1