cmpxchg.h 1.7 KB

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