cmpxchg.h 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  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. #else
  14. #include <asm/cmpxchg-irq.h>
  15. #endif
  16. extern void __xchg_called_with_bad_pointer(void);
  17. #define __xchg(ptr, x, size) \
  18. ({ \
  19. unsigned long __xchg__res; \
  20. volatile void *__xchg_ptr = (ptr); \
  21. switch (size) { \
  22. case 4: \
  23. __xchg__res = xchg_u32(__xchg_ptr, x); \
  24. break; \
  25. case 1: \
  26. __xchg__res = xchg_u8(__xchg_ptr, x); \
  27. break; \
  28. default: \
  29. __xchg_called_with_bad_pointer(); \
  30. __xchg__res = x; \
  31. break; \
  32. } \
  33. \
  34. __xchg__res; \
  35. })
  36. #define xchg(ptr,x) \
  37. ((__typeof__(*(ptr)))__xchg((ptr),(unsigned long)(x), sizeof(*(ptr))))
  38. /* This function doesn't exist, so you'll get a linker error
  39. * if something tries to do an invalid cmpxchg(). */
  40. extern void __cmpxchg_called_with_bad_pointer(void);
  41. static inline unsigned long __cmpxchg(volatile void * ptr, unsigned long old,
  42. unsigned long new, int size)
  43. {
  44. switch (size) {
  45. case 4:
  46. return __cmpxchg_u32(ptr, old, new);
  47. }
  48. __cmpxchg_called_with_bad_pointer();
  49. return old;
  50. }
  51. #define cmpxchg(ptr,o,n) \
  52. ({ \
  53. __typeof__(*(ptr)) _o_ = (o); \
  54. __typeof__(*(ptr)) _n_ = (n); \
  55. (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_, \
  56. (unsigned long)_n_, sizeof(*(ptr))); \
  57. })
  58. #endif /* __ASM_SH_CMPXCHG_H */