cmpxchg.h 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. #ifndef __ASM_CSKY_CMPXCHG_H
  3. #define __ASM_CSKY_CMPXCHG_H
  4. #ifdef CONFIG_CPU_HAS_LDSTEX
  5. #include <asm/barrier.h>
  6. extern void __bad_xchg(void);
  7. #define __xchg(new, ptr, size) \
  8. ({ \
  9. __typeof__(ptr) __ptr = (ptr); \
  10. __typeof__(new) __new = (new); \
  11. __typeof__(*(ptr)) __ret; \
  12. unsigned long tmp; \
  13. switch (size) { \
  14. case 4: \
  15. smp_mb(); \
  16. asm volatile ( \
  17. "1: ldex.w %0, (%3) \n" \
  18. " mov %1, %2 \n" \
  19. " stex.w %1, (%3) \n" \
  20. " bez %1, 1b \n" \
  21. : "=&r" (__ret), "=&r" (tmp) \
  22. : "r" (__new), "r"(__ptr) \
  23. :); \
  24. smp_mb(); \
  25. break; \
  26. default: \
  27. __bad_xchg(); \
  28. } \
  29. __ret; \
  30. })
  31. #define xchg(ptr, x) (__xchg((x), (ptr), sizeof(*(ptr))))
  32. #define __cmpxchg(ptr, old, new, size) \
  33. ({ \
  34. __typeof__(ptr) __ptr = (ptr); \
  35. __typeof__(new) __new = (new); \
  36. __typeof__(new) __tmp; \
  37. __typeof__(old) __old = (old); \
  38. __typeof__(*(ptr)) __ret; \
  39. switch (size) { \
  40. case 4: \
  41. smp_mb(); \
  42. asm volatile ( \
  43. "1: ldex.w %0, (%3) \n" \
  44. " cmpne %0, %4 \n" \
  45. " bt 2f \n" \
  46. " mov %1, %2 \n" \
  47. " stex.w %1, (%3) \n" \
  48. " bez %1, 1b \n" \
  49. "2: \n" \
  50. : "=&r" (__ret), "=&r" (__tmp) \
  51. : "r" (__new), "r"(__ptr), "r"(__old) \
  52. :); \
  53. smp_mb(); \
  54. break; \
  55. default: \
  56. __bad_xchg(); \
  57. } \
  58. __ret; \
  59. })
  60. #define cmpxchg(ptr, o, n) \
  61. (__cmpxchg((ptr), (o), (n), sizeof(*(ptr))))
  62. #else
  63. #include <asm-generic/cmpxchg.h>
  64. #endif
  65. #endif /* __ASM_CSKY_CMPXCHG_H */