atomic.h 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. /*
  2. * Copyright (C) 2014 Stefan Kristiansson <[email protected]>
  3. *
  4. * This file is licensed under the terms of the GNU General Public License
  5. * version 2. This program is licensed "as is" without any warranty of any
  6. * kind, whether express or implied.
  7. */
  8. #ifndef __ASM_OPENRISC_BITOPS_ATOMIC_H
  9. #define __ASM_OPENRISC_BITOPS_ATOMIC_H
  10. static inline void set_bit(int nr, volatile unsigned long *addr)
  11. {
  12. unsigned long mask = BIT_MASK(nr);
  13. unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
  14. unsigned long tmp;
  15. __asm__ __volatile__(
  16. "1: l.lwa %0,0(%1) \n"
  17. " l.or %0,%0,%2 \n"
  18. " l.swa 0(%1),%0 \n"
  19. " l.bnf 1b \n"
  20. " l.nop \n"
  21. : "=&r"(tmp)
  22. : "r"(p), "r"(mask)
  23. : "cc", "memory");
  24. }
  25. static inline void clear_bit(int nr, volatile unsigned long *addr)
  26. {
  27. unsigned long mask = BIT_MASK(nr);
  28. unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
  29. unsigned long tmp;
  30. __asm__ __volatile__(
  31. "1: l.lwa %0,0(%1) \n"
  32. " l.and %0,%0,%2 \n"
  33. " l.swa 0(%1),%0 \n"
  34. " l.bnf 1b \n"
  35. " l.nop \n"
  36. : "=&r"(tmp)
  37. : "r"(p), "r"(~mask)
  38. : "cc", "memory");
  39. }
  40. static inline void change_bit(int nr, volatile unsigned long *addr)
  41. {
  42. unsigned long mask = BIT_MASK(nr);
  43. unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
  44. unsigned long tmp;
  45. __asm__ __volatile__(
  46. "1: l.lwa %0,0(%1) \n"
  47. " l.xor %0,%0,%2 \n"
  48. " l.swa 0(%1),%0 \n"
  49. " l.bnf 1b \n"
  50. " l.nop \n"
  51. : "=&r"(tmp)
  52. : "r"(p), "r"(mask)
  53. : "cc", "memory");
  54. }
  55. static inline int test_and_set_bit(int nr, volatile unsigned long *addr)
  56. {
  57. unsigned long mask = BIT_MASK(nr);
  58. unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
  59. unsigned long old;
  60. unsigned long tmp;
  61. __asm__ __volatile__(
  62. "1: l.lwa %0,0(%2) \n"
  63. " l.or %1,%0,%3 \n"
  64. " l.swa 0(%2),%1 \n"
  65. " l.bnf 1b \n"
  66. " l.nop \n"
  67. : "=&r"(old), "=&r"(tmp)
  68. : "r"(p), "r"(mask)
  69. : "cc", "memory");
  70. return (old & mask) != 0;
  71. }
  72. static inline int test_and_clear_bit(int nr, volatile unsigned long *addr)
  73. {
  74. unsigned long mask = BIT_MASK(nr);
  75. unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
  76. unsigned long old;
  77. unsigned long tmp;
  78. __asm__ __volatile__(
  79. "1: l.lwa %0,0(%2) \n"
  80. " l.and %1,%0,%3 \n"
  81. " l.swa 0(%2),%1 \n"
  82. " l.bnf 1b \n"
  83. " l.nop \n"
  84. : "=&r"(old), "=&r"(tmp)
  85. : "r"(p), "r"(~mask)
  86. : "cc", "memory");
  87. return (old & mask) != 0;
  88. }
  89. static inline int test_and_change_bit(int nr, volatile unsigned long *addr)
  90. {
  91. unsigned long mask = BIT_MASK(nr);
  92. unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
  93. unsigned long old;
  94. unsigned long tmp;
  95. __asm__ __volatile__(
  96. "1: l.lwa %0,0(%2) \n"
  97. " l.xor %1,%0,%3 \n"
  98. " l.swa 0(%2),%1 \n"
  99. " l.bnf 1b \n"
  100. " l.nop \n"
  101. : "=&r"(old), "=&r"(tmp)
  102. : "r"(p), "r"(mask)
  103. : "cc", "memory");
  104. return (old & mask) != 0;
  105. }
  106. #endif /* __ASM_OPENRISC_BITOPS_ATOMIC_H */