cmpxchg.h 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. /*
  2. * Port on Texas Instruments TMS320C6x architecture
  3. *
  4. * Copyright (C) 2004, 2009, 2010, 2011 Texas Instruments Incorporated
  5. * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com)
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License version 2 as
  9. * published by the Free Software Foundation.
  10. */
  11. #ifndef _ASM_C6X_CMPXCHG_H
  12. #define _ASM_C6X_CMPXCHG_H
  13. #include <linux/irqflags.h>
  14. /*
  15. * Misc. functions
  16. */
  17. static inline unsigned int __xchg(unsigned int x, volatile void *ptr, int size)
  18. {
  19. unsigned int tmp;
  20. unsigned long flags;
  21. local_irq_save(flags);
  22. switch (size) {
  23. case 1:
  24. tmp = 0;
  25. tmp = *((unsigned char *) ptr);
  26. *((unsigned char *) ptr) = (unsigned char) x;
  27. break;
  28. case 2:
  29. tmp = 0;
  30. tmp = *((unsigned short *) ptr);
  31. *((unsigned short *) ptr) = x;
  32. break;
  33. case 4:
  34. tmp = 0;
  35. tmp = *((unsigned int *) ptr);
  36. *((unsigned int *) ptr) = x;
  37. break;
  38. }
  39. local_irq_restore(flags);
  40. return tmp;
  41. }
  42. #define xchg(ptr, x) \
  43. ((__typeof__(*(ptr)))__xchg((unsigned int)(x), (void *) (ptr), \
  44. sizeof(*(ptr))))
  45. #include <asm-generic/cmpxchg-local.h>
  46. /*
  47. * cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make
  48. * them available.
  49. */
  50. #define cmpxchg_local(ptr, o, n) \
  51. ((__typeof__(*(ptr)))__cmpxchg_local_generic((ptr), \
  52. (unsigned long)(o), \
  53. (unsigned long)(n), \
  54. sizeof(*(ptr))))
  55. #define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n))
  56. #include <asm-generic/cmpxchg.h>
  57. #endif /* _ASM_C6X_CMPXCHG_H */