Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Move the asm-generic/system.h xchg() implementation to asm-generic/cmpxchg.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>

+80 -77
+80 -7
include/asm-generic/cmpxchg.h
··· 1 + /* 2 + * Generic UP xchg and cmpxchg using interrupt disablement. Does not 3 + * support SMP. 4 + */ 5 + 1 6 #ifndef __ASM_GENERIC_CMPXCHG_H 2 7 #define __ASM_GENERIC_CMPXCHG_H 3 8 4 - /* 5 - * Generic cmpxchg 6 - * 7 - * Uses the local cmpxchg. Does not support SMP. 8 - */ 9 9 #ifdef CONFIG_SMP 10 10 #error "Cannot use generic cmpxchg on SMP" 11 11 #endif 12 12 13 - #include <asm-generic/cmpxchg-local.h> 13 + #include <linux/irqflags.h> 14 + 15 + #ifndef xchg 16 + 17 + /* 18 + * This function doesn't exist, so you'll get a linker error if 19 + * something tries to do an invalidly-sized xchg(). 20 + */ 21 + extern void __xchg_called_with_bad_pointer(void); 22 + 23 + static inline 24 + unsigned long __xchg(unsigned long x, volatile void *ptr, int size) 25 + { 26 + unsigned long ret, flags; 27 + 28 + switch (size) { 29 + case 1: 30 + #ifdef __xchg_u8 31 + return __xchg_u8(x, ptr); 32 + #else 33 + local_irq_save(flags); 34 + ret = *(volatile u8 *)ptr; 35 + *(volatile u8 *)ptr = x; 36 + local_irq_restore(flags); 37 + return ret; 38 + #endif /* __xchg_u8 */ 39 + 40 + case 2: 41 + #ifdef __xchg_u16 42 + return __xchg_u16(x, ptr); 43 + #else 44 + local_irq_save(flags); 45 + ret = *(volatile u16 *)ptr; 46 + *(volatile u16 *)ptr = x; 47 + local_irq_restore(flags); 48 + return ret; 49 + #endif /* __xchg_u16 */ 50 + 51 + case 4: 52 + #ifdef __xchg_u32 53 + return __xchg_u32(x, ptr); 54 + #else 55 + local_irq_save(flags); 56 + ret = *(volatile u32 *)ptr; 57 + *(volatile u32 *)ptr = x; 58 + local_irq_restore(flags); 59 + return ret; 60 + #endif /* __xchg_u32 */ 61 + 62 + #ifdef CONFIG_64BIT 63 + case 8: 64 + #ifdef __xchg_u64 65 + return __xchg_u64(x, ptr); 66 + #else 67 + local_irq_save(flags); 68 + ret = *(volatile u64 *)ptr; 69 + *(volatile u64 *)ptr = x; 70 + local_irq_restore(flags); 71 + return ret; 72 + #endif /* __xchg_u64 */ 73 + #endif /* CONFIG_64BIT */ 74 + 75 + default: 76 + __xchg_called_with_bad_pointer(); 77 + return x; 78 + } 79 + } 80 + 81 + #define xchg(ptr, x) \ 82 + ((__typeof__(*(ptr))) __xchg((unsigned long)(x), (ptr), sizeof(*(ptr)))) 83 + 84 + #endif /* xchg */ 14 85 15 86 /* 16 87 * Atomic compare and exchange. ··· 89 18 * Do not define __HAVE_ARCH_CMPXCHG because we want to use it to check whether 90 19 * a cmpxchg primitive faster than repeated local irq save/restore exists. 91 20 */ 21 + #include <asm-generic/cmpxchg-local.h> 22 + 92 23 #define cmpxchg(ptr, o, n) cmpxchg_local((ptr), (o), (n)) 93 24 #define cmpxchg64(ptr, o, n) cmpxchg64_local((ptr), (o), (n)) 94 25 95 - #endif 26 + #endif /* __ASM_GENERIC_CMPXCHG_H */
-70
include/asm-generic/system.h
··· 17 17 #ifndef __ASSEMBLY__ 18 18 19 19 #include <linux/types.h> 20 - #include <linux/irqflags.h> 21 20 22 21 #include <asm/barrier.h> 23 22 #include <asm/cmpxchg.h> ··· 32 33 } while (0) 33 34 34 35 #define arch_align_stack(x) (x) 35 - 36 - /* 37 - * we make sure local_irq_enable() doesn't cause priority inversion 38 - */ 39 - 40 - /* This function doesn't exist, so you'll get a linker error 41 - * if something tries to do an invalid xchg(). */ 42 - extern void __xchg_called_with_bad_pointer(void); 43 - 44 - static inline 45 - unsigned long __xchg(unsigned long x, volatile void *ptr, int size) 46 - { 47 - unsigned long ret, flags; 48 - 49 - switch (size) { 50 - case 1: 51 - #ifdef __xchg_u8 52 - return __xchg_u8(x, ptr); 53 - #else 54 - local_irq_save(flags); 55 - ret = *(volatile u8 *)ptr; 56 - *(volatile u8 *)ptr = x; 57 - local_irq_restore(flags); 58 - return ret; 59 - #endif /* __xchg_u8 */ 60 - 61 - case 2: 62 - #ifdef __xchg_u16 63 - return __xchg_u16(x, ptr); 64 - #else 65 - local_irq_save(flags); 66 - ret = *(volatile u16 *)ptr; 67 - *(volatile u16 *)ptr = x; 68 - local_irq_restore(flags); 69 - return ret; 70 - #endif /* __xchg_u16 */ 71 - 72 - case 4: 73 - #ifdef __xchg_u32 74 - return __xchg_u32(x, ptr); 75 - #else 76 - local_irq_save(flags); 77 - ret = *(volatile u32 *)ptr; 78 - *(volatile u32 *)ptr = x; 79 - local_irq_restore(flags); 80 - return ret; 81 - #endif /* __xchg_u32 */ 82 - 83 - #ifdef CONFIG_64BIT 84 - case 8: 85 - #ifdef __xchg_u64 86 - return __xchg_u64(x, ptr); 87 - #else 88 - local_irq_save(flags); 89 - ret = *(volatile u64 *)ptr; 90 - *(volatile u64 *)ptr = x; 91 - local_irq_restore(flags); 92 - return ret; 93 - #endif /* __xchg_u64 */ 94 - #endif /* CONFIG_64BIT */ 95 - 96 - default: 97 - __xchg_called_with_bad_pointer(); 98 - return x; 99 - } 100 - } 101 - 102 - #define xchg(ptr, x) \ 103 - ((__typeof__(*(ptr))) __xchg((unsigned long)(x), (ptr), sizeof(*(ptr)))) 104 36 105 37 #endif /* !__ASSEMBLY__ */ 106 38