18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci 38c2ecf20Sopenharmony_ci#ifndef __ASM_CSKY_CMPXCHG_H 48c2ecf20Sopenharmony_ci#define __ASM_CSKY_CMPXCHG_H 58c2ecf20Sopenharmony_ci 68c2ecf20Sopenharmony_ci#ifdef CONFIG_CPU_HAS_LDSTEX 78c2ecf20Sopenharmony_ci#include <asm/barrier.h> 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ciextern void __bad_xchg(void); 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci#define __xchg(new, ptr, size) \ 128c2ecf20Sopenharmony_ci({ \ 138c2ecf20Sopenharmony_ci __typeof__(ptr) __ptr = (ptr); \ 148c2ecf20Sopenharmony_ci __typeof__(new) __new = (new); \ 158c2ecf20Sopenharmony_ci __typeof__(*(ptr)) __ret; \ 168c2ecf20Sopenharmony_ci unsigned long tmp; \ 178c2ecf20Sopenharmony_ci switch (size) { \ 188c2ecf20Sopenharmony_ci case 4: \ 198c2ecf20Sopenharmony_ci smp_mb(); \ 208c2ecf20Sopenharmony_ci asm volatile ( \ 218c2ecf20Sopenharmony_ci "1: ldex.w %0, (%3) \n" \ 228c2ecf20Sopenharmony_ci " mov %1, %2 \n" \ 238c2ecf20Sopenharmony_ci " stex.w %1, (%3) \n" \ 248c2ecf20Sopenharmony_ci " bez %1, 1b \n" \ 258c2ecf20Sopenharmony_ci : "=&r" (__ret), "=&r" (tmp) \ 268c2ecf20Sopenharmony_ci : "r" (__new), "r"(__ptr) \ 278c2ecf20Sopenharmony_ci :); \ 288c2ecf20Sopenharmony_ci smp_mb(); \ 298c2ecf20Sopenharmony_ci break; \ 308c2ecf20Sopenharmony_ci default: \ 318c2ecf20Sopenharmony_ci __bad_xchg(); \ 328c2ecf20Sopenharmony_ci } \ 338c2ecf20Sopenharmony_ci __ret; \ 348c2ecf20Sopenharmony_ci}) 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_ci#define xchg(ptr, x) (__xchg((x), (ptr), sizeof(*(ptr)))) 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_ci#define __cmpxchg(ptr, old, new, size) \ 398c2ecf20Sopenharmony_ci({ \ 408c2ecf20Sopenharmony_ci __typeof__(ptr) __ptr = (ptr); \ 418c2ecf20Sopenharmony_ci __typeof__(new) __new = (new); \ 428c2ecf20Sopenharmony_ci __typeof__(new) __tmp; \ 438c2ecf20Sopenharmony_ci __typeof__(old) __old = (old); \ 448c2ecf20Sopenharmony_ci __typeof__(*(ptr)) __ret; \ 458c2ecf20Sopenharmony_ci switch (size) { \ 468c2ecf20Sopenharmony_ci case 4: \ 478c2ecf20Sopenharmony_ci smp_mb(); \ 488c2ecf20Sopenharmony_ci asm volatile ( \ 498c2ecf20Sopenharmony_ci "1: ldex.w %0, (%3) \n" \ 508c2ecf20Sopenharmony_ci " cmpne %0, %4 \n" \ 518c2ecf20Sopenharmony_ci " bt 2f \n" \ 528c2ecf20Sopenharmony_ci " mov %1, %2 \n" \ 538c2ecf20Sopenharmony_ci " stex.w %1, (%3) \n" \ 548c2ecf20Sopenharmony_ci " bez %1, 1b \n" \ 558c2ecf20Sopenharmony_ci "2: \n" \ 568c2ecf20Sopenharmony_ci : "=&r" (__ret), "=&r" (__tmp) \ 578c2ecf20Sopenharmony_ci : "r" (__new), "r"(__ptr), "r"(__old) \ 588c2ecf20Sopenharmony_ci :); \ 598c2ecf20Sopenharmony_ci smp_mb(); \ 608c2ecf20Sopenharmony_ci break; \ 618c2ecf20Sopenharmony_ci default: \ 628c2ecf20Sopenharmony_ci __bad_xchg(); \ 638c2ecf20Sopenharmony_ci } \ 648c2ecf20Sopenharmony_ci __ret; \ 658c2ecf20Sopenharmony_ci}) 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_ci#define cmpxchg(ptr, o, n) \ 688c2ecf20Sopenharmony_ci (__cmpxchg((ptr), (o), (n), sizeof(*(ptr)))) 698c2ecf20Sopenharmony_ci#else 708c2ecf20Sopenharmony_ci#include <asm-generic/cmpxchg.h> 718c2ecf20Sopenharmony_ci#endif 728c2ecf20Sopenharmony_ci 738c2ecf20Sopenharmony_ci#endif /* __ASM_CSKY_CMPXCHG_H */ 74