bitops-cas.h 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. #ifndef __ASM_SH_BITOPS_CAS_H
  3. #define __ASM_SH_BITOPS_CAS_H
  4. static inline unsigned __bo_cas(volatile unsigned *p, unsigned old, unsigned new)
  5. {
  6. __asm__ __volatile__("cas.l %1,%0,@r0"
  7. : "+r"(new)
  8. : "r"(old), "z"(p)
  9. : "t", "memory" );
  10. return new;
  11. }
  12. static inline void set_bit(int nr, volatile void *addr)
  13. {
  14. unsigned mask, old;
  15. volatile unsigned *a = addr;
  16. a += nr >> 5;
  17. mask = 1U << (nr & 0x1f);
  18. do old = *a;
  19. while (__bo_cas(a, old, old|mask) != old);
  20. }
  21. static inline void clear_bit(int nr, volatile void *addr)
  22. {
  23. unsigned mask, old;
  24. volatile unsigned *a = addr;
  25. a += nr >> 5;
  26. mask = 1U << (nr & 0x1f);
  27. do old = *a;
  28. while (__bo_cas(a, old, old&~mask) != old);
  29. }
  30. static inline void change_bit(int nr, volatile void *addr)
  31. {
  32. unsigned mask, old;
  33. volatile unsigned *a = addr;
  34. a += nr >> 5;
  35. mask = 1U << (nr & 0x1f);
  36. do old = *a;
  37. while (__bo_cas(a, old, old^mask) != old);
  38. }
  39. static inline int test_and_set_bit(int nr, volatile void *addr)
  40. {
  41. unsigned mask, old;
  42. volatile unsigned *a = addr;
  43. a += nr >> 5;
  44. mask = 1U << (nr & 0x1f);
  45. do old = *a;
  46. while (__bo_cas(a, old, old|mask) != old);
  47. return !!(old & mask);
  48. }
  49. static inline int test_and_clear_bit(int nr, volatile void *addr)
  50. {
  51. unsigned mask, old;
  52. volatile unsigned *a = addr;
  53. a += nr >> 5;
  54. mask = 1U << (nr & 0x1f);
  55. do old = *a;
  56. while (__bo_cas(a, old, old&~mask) != old);
  57. return !!(old & mask);
  58. }
  59. static inline int test_and_change_bit(int nr, volatile void *addr)
  60. {
  61. unsigned mask, old;
  62. volatile unsigned *a = addr;
  63. a += nr >> 5;
  64. mask = 1U << (nr & 0x1f);
  65. do old = *a;
  66. while (__bo_cas(a, old, old^mask) != old);
  67. return !!(old & mask);
  68. }
  69. #include <asm-generic/bitops/non-atomic.h>
  70. #endif /* __ASM_SH_BITOPS_CAS_H */