diff options
Diffstat (limited to 'arch/powerpc/include/asm/bitops.h')
-rw-r--r-- | arch/powerpc/include/asm/bitops.h | 56 |
1 files changed, 30 insertions, 26 deletions
diff --git a/arch/powerpc/include/asm/bitops.h b/arch/powerpc/include/asm/bitops.h index 56f2f2ea5631..30964ae2d096 100644 --- a/arch/powerpc/include/asm/bitops.h +++ b/arch/powerpc/include/asm/bitops.h | |||
@@ -65,7 +65,7 @@ static __inline__ void fn(unsigned long mask, \ | |||
65 | unsigned long *p = (unsigned long *)_p; \ | 65 | unsigned long *p = (unsigned long *)_p; \ |
66 | __asm__ __volatile__ ( \ | 66 | __asm__ __volatile__ ( \ |
67 | prefix \ | 67 | prefix \ |
68 | "1:" PPC_LLARX "%0,0,%3\n" \ | 68 | "1:" PPC_LLARX(%0,0,%3,0) "\n" \ |
69 | stringify_in_c(op) "%0,%0,%2\n" \ | 69 | stringify_in_c(op) "%0,%0,%2\n" \ |
70 | PPC405_ERR77(0,%3) \ | 70 | PPC405_ERR77(0,%3) \ |
71 | PPC_STLCX "%0,0,%3\n" \ | 71 | PPC_STLCX "%0,0,%3\n" \ |
@@ -78,7 +78,7 @@ static __inline__ void fn(unsigned long mask, \ | |||
78 | 78 | ||
79 | DEFINE_BITOP(set_bits, or, "", "") | 79 | DEFINE_BITOP(set_bits, or, "", "") |
80 | DEFINE_BITOP(clear_bits, andc, "", "") | 80 | DEFINE_BITOP(clear_bits, andc, "", "") |
81 | DEFINE_BITOP(clear_bits_unlock, andc, LWSYNC_ON_SMP, "") | 81 | DEFINE_BITOP(clear_bits_unlock, andc, PPC_RELEASE_BARRIER, "") |
82 | DEFINE_BITOP(change_bits, xor, "", "") | 82 | DEFINE_BITOP(change_bits, xor, "", "") |
83 | 83 | ||
84 | static __inline__ void set_bit(int nr, volatile unsigned long *addr) | 84 | static __inline__ void set_bit(int nr, volatile unsigned long *addr) |
@@ -103,31 +103,35 @@ static __inline__ void change_bit(int nr, volatile unsigned long *addr) | |||
103 | 103 | ||
104 | /* Like DEFINE_BITOP(), with changes to the arguments to 'op' and the output | 104 | /* Like DEFINE_BITOP(), with changes to the arguments to 'op' and the output |
105 | * operands. */ | 105 | * operands. */ |
106 | #define DEFINE_TESTOP(fn, op, prefix, postfix) \ | 106 | #define DEFINE_TESTOP(fn, op, prefix, postfix, eh) \ |
107 | static __inline__ unsigned long fn( \ | 107 | static __inline__ unsigned long fn( \ |
108 | unsigned long mask, \ | 108 | unsigned long mask, \ |
109 | volatile unsigned long *_p) \ | 109 | volatile unsigned long *_p) \ |
110 | { \ | 110 | { \ |
111 | unsigned long old, t; \ | 111 | unsigned long old, t; \ |
112 | unsigned long *p = (unsigned long *)_p; \ | 112 | unsigned long *p = (unsigned long *)_p; \ |
113 | __asm__ __volatile__ ( \ | 113 | __asm__ __volatile__ ( \ |
114 | prefix \ | 114 | prefix \ |
115 | "1:" PPC_LLARX "%0,0,%3\n" \ | 115 | "1:" PPC_LLARX(%0,0,%3,eh) "\n" \ |
116 | stringify_in_c(op) "%1,%0,%2\n" \ | 116 | stringify_in_c(op) "%1,%0,%2\n" \ |
117 | PPC405_ERR77(0,%3) \ | 117 | PPC405_ERR77(0,%3) \ |
118 | PPC_STLCX "%1,0,%3\n" \ | 118 | PPC_STLCX "%1,0,%3\n" \ |
119 | "bne- 1b\n" \ | 119 | "bne- 1b\n" \ |
120 | postfix \ | 120 | postfix \ |
121 | : "=&r" (old), "=&r" (t) \ | 121 | : "=&r" (old), "=&r" (t) \ |
122 | : "r" (mask), "r" (p) \ | 122 | : "r" (mask), "r" (p) \ |
123 | : "cc", "memory"); \ | 123 | : "cc", "memory"); \ |
124 | return (old & mask); \ | 124 | return (old & mask); \ |
125 | } | 125 | } |
126 | 126 | ||
127 | DEFINE_TESTOP(test_and_set_bits, or, LWSYNC_ON_SMP, ISYNC_ON_SMP) | 127 | DEFINE_TESTOP(test_and_set_bits, or, PPC_RELEASE_BARRIER, |
128 | DEFINE_TESTOP(test_and_set_bits_lock, or, "", ISYNC_ON_SMP) | 128 | PPC_ACQUIRE_BARRIER, 0) |
129 | DEFINE_TESTOP(test_and_clear_bits, andc, LWSYNC_ON_SMP, ISYNC_ON_SMP) | 129 | DEFINE_TESTOP(test_and_set_bits_lock, or, "", |
130 | DEFINE_TESTOP(test_and_change_bits, xor, LWSYNC_ON_SMP, ISYNC_ON_SMP) | 130 | PPC_ACQUIRE_BARRIER, 1) |
131 | DEFINE_TESTOP(test_and_clear_bits, andc, PPC_RELEASE_BARRIER, | ||
132 | PPC_ACQUIRE_BARRIER, 0) | ||
133 | DEFINE_TESTOP(test_and_change_bits, xor, PPC_RELEASE_BARRIER, | ||
134 | PPC_ACQUIRE_BARRIER, 0) | ||
131 | 135 | ||
132 | static __inline__ int test_and_set_bit(unsigned long nr, | 136 | static __inline__ int test_and_set_bit(unsigned long nr, |
133 | volatile unsigned long *addr) | 137 | volatile unsigned long *addr) |
@@ -158,7 +162,7 @@ static __inline__ int test_and_change_bit(unsigned long nr, | |||
158 | 162 | ||
159 | static __inline__ void __clear_bit_unlock(int nr, volatile unsigned long *addr) | 163 | static __inline__ void __clear_bit_unlock(int nr, volatile unsigned long *addr) |
160 | { | 164 | { |
161 | __asm__ __volatile__(LWSYNC_ON_SMP "" ::: "memory"); | 165 | __asm__ __volatile__(PPC_RELEASE_BARRIER "" ::: "memory"); |
162 | __clear_bit(nr, addr); | 166 | __clear_bit(nr, addr); |
163 | } | 167 | } |
164 | 168 | ||