^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) #ifndef __ASM_SH_BITOPS_LLSC_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) #define __ASM_SH_BITOPS_LLSC_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) static inline void set_bit(int nr, volatile void *addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) int mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) volatile unsigned int *a = addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) unsigned long tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) a += nr >> 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) mask = 1 << (nr & 0x1f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) __asm__ __volatile__ (
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) "1: \n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) "movli.l @%1, %0 ! set_bit \n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) "or %2, %0 \n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) "movco.l %0, @%1 \n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) "bf 1b \n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) : "=&z" (tmp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) : "r" (a), "r" (mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) : "t", "memory"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) static inline void clear_bit(int nr, volatile void *addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) int mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) volatile unsigned int *a = addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) unsigned long tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) a += nr >> 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) mask = 1 << (nr & 0x1f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) __asm__ __volatile__ (
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) "1: \n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) "movli.l @%1, %0 ! clear_bit \n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) "and %2, %0 \n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) "movco.l %0, @%1 \n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) "bf 1b \n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) : "=&z" (tmp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) : "r" (a), "r" (~mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) : "t", "memory"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) static inline void change_bit(int nr, volatile void *addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) int mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) volatile unsigned int *a = addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) unsigned long tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) a += nr >> 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) mask = 1 << (nr & 0x1f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) __asm__ __volatile__ (
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) "1: \n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) "movli.l @%1, %0 ! change_bit \n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) "xor %2, %0 \n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) "movco.l %0, @%1 \n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) "bf 1b \n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) : "=&z" (tmp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) : "r" (a), "r" (mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) : "t", "memory"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) static inline int test_and_set_bit(int nr, volatile void *addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) int mask, retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) volatile unsigned int *a = addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) unsigned long tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) a += nr >> 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) mask = 1 << (nr & 0x1f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) __asm__ __volatile__ (
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) "1: \n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) "movli.l @%2, %0 ! test_and_set_bit \n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) "mov %0, %1 \n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) "or %3, %0 \n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) "movco.l %0, @%2 \n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) "bf 1b \n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) "and %3, %1 \n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) : "=&z" (tmp), "=&r" (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) : "r" (a), "r" (mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) : "t", "memory"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) return retval != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) static inline int test_and_clear_bit(int nr, volatile void *addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) int mask, retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) volatile unsigned int *a = addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) unsigned long tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) a += nr >> 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) mask = 1 << (nr & 0x1f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) __asm__ __volatile__ (
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) "1: \n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) "movli.l @%2, %0 ! test_and_clear_bit \n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) "mov %0, %1 \n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) "and %4, %0 \n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) "movco.l %0, @%2 \n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) "bf 1b \n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) "and %3, %1 \n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) "synco \n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) : "=&z" (tmp), "=&r" (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) : "r" (a), "r" (mask), "r" (~mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) : "t", "memory"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) return retval != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) static inline int test_and_change_bit(int nr, volatile void *addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) int mask, retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) volatile unsigned int *a = addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) unsigned long tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) a += nr >> 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) mask = 1 << (nr & 0x1f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) __asm__ __volatile__ (
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) "1: \n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) "movli.l @%2, %0 ! test_and_change_bit \n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) "mov %0, %1 \n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) "xor %3, %0 \n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) "movco.l %0, @%2 \n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) "bf 1b \n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) "and %3, %1 \n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) "synco \n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) : "=&z" (tmp), "=&r" (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) : "r" (a), "r" (mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) : "t", "memory"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) return retval != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) #include <asm-generic/bitops/non-atomic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) #endif /* __ASM_SH_BITOPS_LLSC_H */