cmpxchg.h 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. #ifndef __ASM_SH_CMPXCHG_H
  3. #define __ASM_SH_CMPXCHG_H
  4. /*
  5. * Atomic operations that C can't guarantee us. Useful for
  6. * resource counting etc..
  7. */
  8. #include <linux/compiler.h>
  9. #include <linux/types.h>
  10. #include <linux/cmpxchg-emu.h>
  11. #if defined(CONFIG_GUSA_RB)
  12. #include <asm/cmpxchg-grb.h>
  13. #elif defined(CONFIG_CPU_SH4A)
  14. #include <asm/cmpxchg-llsc.h>
  15. #elif defined(CONFIG_CPU_J2) && defined(CONFIG_SMP)
  16. #include <asm/cmpxchg-cas.h>
  17. #else
  18. #include <asm/cmpxchg-irq.h>
  19. #endif
  20. extern void __xchg_called_with_bad_pointer(void);
  21. #define __arch_xchg(ptr, x, size) \
  22. ({ \
  23. unsigned long __xchg__res; \
  24. volatile void *__xchg_ptr = (ptr); \
  25. switch (size) { \
  26. case 4: \
  27. __xchg__res = xchg_u32(__xchg_ptr, x); \
  28. break; \
  29. case 2: \
  30. __xchg__res = xchg_u16(__xchg_ptr, x); \
  31. break; \
  32. case 1: \
  33. __xchg__res = xchg_u8(__xchg_ptr, x); \
  34. break; \
  35. default: \
  36. __xchg_called_with_bad_pointer(); \
  37. __xchg__res = x; \
  38. break; \
  39. } \
  40. \
  41. __xchg__res; \
  42. })
  43. #define arch_xchg(ptr,x) \
  44. ((__typeof__(*(ptr)))__arch_xchg((ptr),(unsigned long)(x), sizeof(*(ptr))))
  45. /* This function doesn't exist, so you'll get a linker error
  46. * if something tries to do an invalid cmpxchg(). */
  47. extern void __cmpxchg_called_with_bad_pointer(void);
  48. static inline unsigned long __cmpxchg(volatile void * ptr, unsigned long old,
  49. unsigned long new, int size)
  50. {
  51. switch (size) {
  52. case 1:
  53. return cmpxchg_emu_u8(ptr, old, new);
  54. case 4:
  55. return __cmpxchg_u32(ptr, old, new);
  56. }
  57. __cmpxchg_called_with_bad_pointer();
  58. return old;
  59. }
  60. #define arch_cmpxchg(ptr,o,n) \
  61. ({ \
  62. __typeof__(*(ptr)) _o_ = (o); \
  63. __typeof__(*(ptr)) _n_ = (n); \
  64. (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_, \
  65. (unsigned long)_n_, sizeof(*(ptr))); \
  66. })
  67. #include <asm-generic/cmpxchg-local.h>
  68. #define arch_cmpxchg_local(ptr, o, n) ({ \
  69. (__typeof__(*ptr))__generic_cmpxchg_local((ptr), \
  70. (unsigned long)(o), \
  71. (unsigned long)(n), \
  72. sizeof(*(ptr))); \
  73. })
  74. #endif /* __ASM_SH_CMPXCHG_H */