cmpxchg.h 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. #ifndef __ASM_CRIS_CMPXCHG__
  2. #define __ASM_CRIS_CMPXCHG__
  3. #include <linux/irqflags.h>
  4. static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
  5. {
  6. /* since Etrax doesn't have any atomic xchg instructions, we need to disable
  7. irq's (if enabled) and do it with move.d's */
  8. unsigned long flags,temp;
  9. local_irq_save(flags); /* save flags, including irq enable bit and shut off irqs */
  10. switch (size) {
  11. case 1:
  12. *((unsigned char *)&temp) = x;
  13. x = *(unsigned char *)ptr;
  14. *(unsigned char *)ptr = *((unsigned char *)&temp);
  15. break;
  16. case 2:
  17. *((unsigned short *)&temp) = x;
  18. x = *(unsigned short *)ptr;
  19. *(unsigned short *)ptr = *((unsigned short *)&temp);
  20. break;
  21. case 4:
  22. temp = x;
  23. x = *(unsigned long *)ptr;
  24. *(unsigned long *)ptr = temp;
  25. break;
  26. }
  27. local_irq_restore(flags); /* restore irq enable bit */
  28. return x;
  29. }
  30. #define xchg(ptr,x) \
  31. ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
  32. #define tas(ptr) (xchg((ptr),1))
  33. #include <asm-generic/cmpxchg-local.h>
  34. /*
  35. * cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make
  36. * them available.
  37. */
  38. #define cmpxchg_local(ptr, o, n) \
  39. ((__typeof__(*(ptr)))__cmpxchg_local_generic((ptr), (unsigned long)(o),\
  40. (unsigned long)(n), sizeof(*(ptr))))
  41. #define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n))
  42. #ifndef CONFIG_SMP
  43. #include <asm-generic/cmpxchg.h>
  44. #endif
  45. #endif /* __ASM_CRIS_CMPXCHG__ */