bitops-cas.h 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  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 */