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