-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Move the asm-generic/system.h xchg() implementation to asm-generic/cm…
…pxchg.h Move the asm-generic/system.h xchg() implementation to asm-generic/cmpxchg.h to simplify disintegration of asm/system.h. Signed-off-by: David Howells <dhowells@redhat.com> Acked-by: Arnd Bergmann <arnd@arndb.de>
- Loading branch information
David Howells
committed
Mar 28, 2012
1 parent
885df91
commit b4816af
Showing
2 changed files
with
80 additions
and
77 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,24 +1,97 @@ | ||
/* | ||
* Generic UP xchg and cmpxchg using interrupt disablement. Does not | ||
* support SMP. | ||
*/ | ||
|
||
#ifndef __ASM_GENERIC_CMPXCHG_H | ||
#define __ASM_GENERIC_CMPXCHG_H | ||
|
||
/* | ||
* Generic cmpxchg | ||
* | ||
* Uses the local cmpxchg. Does not support SMP. | ||
*/ | ||
#ifdef CONFIG_SMP | ||
#error "Cannot use generic cmpxchg on SMP" | ||
#endif | ||
|
||
#include <asm-generic/cmpxchg-local.h> | ||
#include <linux/irqflags.h> | ||
|
||
#ifndef xchg | ||
|
||
/* | ||
* This function doesn't exist, so you'll get a linker error if | ||
* something tries to do an invalidly-sized xchg(). | ||
*/ | ||
extern void __xchg_called_with_bad_pointer(void); | ||
|
||
static inline | ||
unsigned long __xchg(unsigned long x, volatile void *ptr, int size) | ||
{ | ||
unsigned long ret, flags; | ||
|
||
switch (size) { | ||
case 1: | ||
#ifdef __xchg_u8 | ||
return __xchg_u8(x, ptr); | ||
#else | ||
local_irq_save(flags); | ||
ret = *(volatile u8 *)ptr; | ||
*(volatile u8 *)ptr = x; | ||
local_irq_restore(flags); | ||
return ret; | ||
#endif /* __xchg_u8 */ | ||
|
||
case 2: | ||
#ifdef __xchg_u16 | ||
return __xchg_u16(x, ptr); | ||
#else | ||
local_irq_save(flags); | ||
ret = *(volatile u16 *)ptr; | ||
*(volatile u16 *)ptr = x; | ||
local_irq_restore(flags); | ||
return ret; | ||
#endif /* __xchg_u16 */ | ||
|
||
case 4: | ||
#ifdef __xchg_u32 | ||
return __xchg_u32(x, ptr); | ||
#else | ||
local_irq_save(flags); | ||
ret = *(volatile u32 *)ptr; | ||
*(volatile u32 *)ptr = x; | ||
local_irq_restore(flags); | ||
return ret; | ||
#endif /* __xchg_u32 */ | ||
|
||
#ifdef CONFIG_64BIT | ||
case 8: | ||
#ifdef __xchg_u64 | ||
return __xchg_u64(x, ptr); | ||
#else | ||
local_irq_save(flags); | ||
ret = *(volatile u64 *)ptr; | ||
*(volatile u64 *)ptr = x; | ||
local_irq_restore(flags); | ||
return ret; | ||
#endif /* __xchg_u64 */ | ||
#endif /* CONFIG_64BIT */ | ||
|
||
default: | ||
__xchg_called_with_bad_pointer(); | ||
return x; | ||
} | ||
} | ||
|
||
#define xchg(ptr, x) \ | ||
((__typeof__(*(ptr))) __xchg((unsigned long)(x), (ptr), sizeof(*(ptr)))) | ||
|
||
#endif /* xchg */ | ||
|
||
/* | ||
* Atomic compare and exchange. | ||
* | ||
* Do not define __HAVE_ARCH_CMPXCHG because we want to use it to check whether | ||
* a cmpxchg primitive faster than repeated local irq save/restore exists. | ||
*/ | ||
#include <asm-generic/cmpxchg-local.h> | ||
|
||
#define cmpxchg(ptr, o, n) cmpxchg_local((ptr), (o), (n)) | ||
#define cmpxchg64(ptr, o, n) cmpxchg64_local((ptr), (o), (n)) | ||
|
||
#endif | ||
#endif /* __ASM_GENERIC_CMPXCHG_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters