diff options
author | Will Deacon <will.deacon@arm.com> | 2013-03-28 06:25:03 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2013-04-03 12:00:00 -0400 |
commit | 4fd75911f6970478444eece952dacb2db9d1e5a5 (patch) | |
tree | 310800b1a6ad447f697f1dccd12d3e6cf11179cf /arch/arm/include | |
parent | 029baf14a027a44b3ac8a9fe5cb1e516cbb9007e (diff) |
ARM: 7687/1: atomics: don't use exclusives for atomic64 read/set with LPAE
To ease page table updates with 64-bit descriptors, CPUs implementing
LPAE are required to implement ldrd/strd as atomic operations.
This patch uses these accessors instead of the exclusive variants when
performing atomic64_{read,set} on LPAE systems.
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/include')
-rw-r--r-- | arch/arm/include/asm/atomic.h | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/arch/arm/include/asm/atomic.h b/arch/arm/include/asm/atomic.h index c79f61faa3a5..da1c77d39327 100644 --- a/arch/arm/include/asm/atomic.h +++ b/arch/arm/include/asm/atomic.h | |||
@@ -243,6 +243,29 @@ typedef struct { | |||
243 | 243 | ||
244 | #define ATOMIC64_INIT(i) { (i) } | 244 | #define ATOMIC64_INIT(i) { (i) } |
245 | 245 | ||
246 | #ifdef CONFIG_ARM_LPAE | ||
247 | static inline u64 atomic64_read(const atomic64_t *v) | ||
248 | { | ||
249 | u64 result; | ||
250 | |||
251 | __asm__ __volatile__("@ atomic64_read\n" | ||
252 | " ldrd %0, %H0, [%1]" | ||
253 | : "=&r" (result) | ||
254 | : "r" (&v->counter), "Qo" (v->counter) | ||
255 | ); | ||
256 | |||
257 | return result; | ||
258 | } | ||
259 | |||
260 | static inline void atomic64_set(atomic64_t *v, u64 i) | ||
261 | { | ||
262 | __asm__ __volatile__("@ atomic64_set\n" | ||
263 | " strd %2, %H2, [%1]" | ||
264 | : "=Qo" (v->counter) | ||
265 | : "r" (&v->counter), "r" (i) | ||
266 | ); | ||
267 | } | ||
268 | #else | ||
246 | static inline u64 atomic64_read(const atomic64_t *v) | 269 | static inline u64 atomic64_read(const atomic64_t *v) |
247 | { | 270 | { |
248 | u64 result; | 271 | u64 result; |
@@ -269,6 +292,7 @@ static inline void atomic64_set(atomic64_t *v, u64 i) | |||
269 | : "r" (&v->counter), "r" (i) | 292 | : "r" (&v->counter), "r" (i) |
270 | : "cc"); | 293 | : "cc"); |
271 | } | 294 | } |
295 | #endif | ||
272 | 296 | ||
273 | static inline void atomic64_add(u64 i, atomic64_t *v) | 297 | static inline void atomic64_add(u64 i, atomic64_t *v) |
274 | { | 298 | { |