atomic-irq.h 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. #ifndef __ASM_SH_ATOMIC_IRQ_H
  3. #define __ASM_SH_ATOMIC_IRQ_H
  4. #include <linux/irqflags.h>
  5. /*
  6. * To get proper branch prediction for the main line, we must branch
  7. * forward to code at the end of this object's .text section, then
  8. * branch back to restart the operation.
  9. */
  10. #define ATOMIC_OP(op, c_op) \
  11. static inline void atomic_##op(int i, atomic_t *v) \
  12. { \
  13. unsigned long flags; \
  14. \
  15. raw_local_irq_save(flags); \
  16. v->counter c_op i; \
  17. raw_local_irq_restore(flags); \
  18. }
  19. #define ATOMIC_OP_RETURN(op, c_op) \
  20. static inline int atomic_##op##_return(int i, atomic_t *v) \
  21. { \
  22. unsigned long temp, flags; \
  23. \
  24. raw_local_irq_save(flags); \
  25. temp = v->counter; \
  26. temp c_op i; \
  27. v->counter = temp; \
  28. raw_local_irq_restore(flags); \
  29. \
  30. return temp; \
  31. }
  32. #define ATOMIC_FETCH_OP(op, c_op) \
  33. static inline int atomic_fetch_##op(int i, atomic_t *v) \
  34. { \
  35. unsigned long temp, flags; \
  36. \
  37. raw_local_irq_save(flags); \
  38. temp = v->counter; \
  39. v->counter c_op i; \
  40. raw_local_irq_restore(flags); \
  41. \
  42. return temp; \
  43. }
  44. #define ATOMIC_OPS(op, c_op) \
  45. ATOMIC_OP(op, c_op) \
  46. ATOMIC_OP_RETURN(op, c_op) \
  47. ATOMIC_FETCH_OP(op, c_op)
  48. ATOMIC_OPS(add, +=)
  49. ATOMIC_OPS(sub, -=)
  50. #undef ATOMIC_OPS
  51. #define ATOMIC_OPS(op, c_op) \
  52. ATOMIC_OP(op, c_op) \
  53. ATOMIC_FETCH_OP(op, c_op)
  54. ATOMIC_OPS(and, &=)
  55. ATOMIC_OPS(or, |=)
  56. ATOMIC_OPS(xor, ^=)
  57. #undef ATOMIC_OPS
  58. #undef ATOMIC_FETCH_OP
  59. #undef ATOMIC_OP_RETURN
  60. #undef ATOMIC_OP
  61. #endif /* __ASM_SH_ATOMIC_IRQ_H */