atomic.h 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. #ifndef __ARCH_H8300_ATOMIC__
  2. #define __ARCH_H8300_ATOMIC__
  3. #include <linux/types.h>
  4. #include <asm/cmpxchg.h>
  5. /*
  6. * Atomic operations that C can't guarantee us. Useful for
  7. * resource counting etc..
  8. */
  9. #define ATOMIC_INIT(i) { (i) }
  10. #define atomic_read(v) READ_ONCE((v)->counter)
  11. #define atomic_set(v, i) WRITE_ONCE(((v)->counter), (i))
  12. #include <linux/kernel.h>
  13. #define ATOMIC_OP_RETURN(op, c_op) \
  14. static inline int atomic_##op##_return(int i, atomic_t *v) \
  15. { \
  16. h8300flags flags; \
  17. int ret; \
  18. \
  19. flags = arch_local_irq_save(); \
  20. ret = v->counter c_op i; \
  21. arch_local_irq_restore(flags); \
  22. return ret; \
  23. }
  24. #define ATOMIC_OP(op, c_op) \
  25. static inline void atomic_##op(int i, atomic_t *v) \
  26. { \
  27. h8300flags flags; \
  28. \
  29. flags = arch_local_irq_save(); \
  30. v->counter c_op i; \
  31. arch_local_irq_restore(flags); \
  32. }
  33. ATOMIC_OP_RETURN(add, +=)
  34. ATOMIC_OP_RETURN(sub, -=)
  35. ATOMIC_OP(and, &=)
  36. ATOMIC_OP(or, |=)
  37. ATOMIC_OP(xor, ^=)
  38. #undef ATOMIC_OP_RETURN
  39. #undef ATOMIC_OP
  40. #define atomic_add(i, v) (void)atomic_add_return(i, v)
  41. #define atomic_add_negative(a, v) (atomic_add_return((a), (v)) < 0)
  42. #define atomic_sub(i, v) (void)atomic_sub_return(i, v)
  43. #define atomic_sub_and_test(i, v) (atomic_sub_return(i, v) == 0)
  44. #define atomic_inc_return(v) atomic_add_return(1, v)
  45. #define atomic_dec_return(v) atomic_sub_return(1, v)
  46. #define atomic_inc(v) (void)atomic_inc_return(v)
  47. #define atomic_inc_and_test(v) (atomic_inc_return(v) == 0)
  48. #define atomic_dec(v) (void)atomic_dec_return(v)
  49. #define atomic_dec_and_test(v) (atomic_dec_return(v) == 0)
  50. static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
  51. {
  52. int ret;
  53. h8300flags flags;
  54. flags = arch_local_irq_save();
  55. ret = v->counter;
  56. if (likely(ret == old))
  57. v->counter = new;
  58. arch_local_irq_restore(flags);
  59. return ret;
  60. }
  61. static inline int __atomic_add_unless(atomic_t *v, int a, int u)
  62. {
  63. int ret;
  64. h8300flags flags;
  65. flags = arch_local_irq_save();
  66. ret = v->counter;
  67. if (ret != u)
  68. v->counter += a;
  69. arch_local_irq_restore(flags);
  70. return ret;
  71. }
  72. #endif /* __ARCH_H8300_ATOMIC __ */