diff options
Diffstat (limited to 'arch/m68k')
-rw-r--r-- | arch/m68k/include/asm/system.h | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/arch/m68k/include/asm/system.h b/arch/m68k/include/asm/system.h index 47b01f4726bc..a10c4d1241de 100644 --- a/arch/m68k/include/asm/system.h +++ b/arch/m68k/include/asm/system.h | |||
@@ -68,6 +68,8 @@ asmlinkage void resume(void); | |||
68 | struct __xchg_dummy { unsigned long a[100]; }; | 68 | struct __xchg_dummy { unsigned long a[100]; }; |
69 | #define __xg(x) ((volatile struct __xchg_dummy *)(x)) | 69 | #define __xg(x) ((volatile struct __xchg_dummy *)(x)) |
70 | 70 | ||
71 | extern unsigned long __invalid_xchg_size(unsigned long, volatile void *, int); | ||
72 | |||
71 | #ifndef CONFIG_RMW_INSNS | 73 | #ifndef CONFIG_RMW_INSNS |
72 | static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size) | 74 | static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size) |
73 | { | 75 | { |
@@ -92,7 +94,8 @@ static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int siz | |||
92 | x = tmp; | 94 | x = tmp; |
93 | break; | 95 | break; |
94 | default: | 96 | default: |
95 | BUG(); | 97 | tmp = __invalid_xchg_size(x, ptr, size); |
98 | break; | ||
96 | } | 99 | } |
97 | 100 | ||
98 | local_irq_restore(flags); | 101 | local_irq_restore(flags); |
@@ -102,7 +105,7 @@ static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int siz | |||
102 | static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size) | 105 | static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size) |
103 | { | 106 | { |
104 | switch (size) { | 107 | switch (size) { |
105 | case 1: | 108 | case 1: |
106 | __asm__ __volatile__ | 109 | __asm__ __volatile__ |
107 | ("moveb %2,%0\n\t" | 110 | ("moveb %2,%0\n\t" |
108 | "1:\n\t" | 111 | "1:\n\t" |
@@ -110,7 +113,7 @@ static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int siz | |||
110 | "jne 1b" | 113 | "jne 1b" |
111 | : "=&d" (x) : "d" (x), "m" (*__xg(ptr)) : "memory"); | 114 | : "=&d" (x) : "d" (x), "m" (*__xg(ptr)) : "memory"); |
112 | break; | 115 | break; |
113 | case 2: | 116 | case 2: |
114 | __asm__ __volatile__ | 117 | __asm__ __volatile__ |
115 | ("movew %2,%0\n\t" | 118 | ("movew %2,%0\n\t" |
116 | "1:\n\t" | 119 | "1:\n\t" |
@@ -118,7 +121,7 @@ static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int siz | |||
118 | "jne 1b" | 121 | "jne 1b" |
119 | : "=&d" (x) : "d" (x), "m" (*__xg(ptr)) : "memory"); | 122 | : "=&d" (x) : "d" (x), "m" (*__xg(ptr)) : "memory"); |
120 | break; | 123 | break; |
121 | case 4: | 124 | case 4: |
122 | __asm__ __volatile__ | 125 | __asm__ __volatile__ |
123 | ("movel %2,%0\n\t" | 126 | ("movel %2,%0\n\t" |
124 | "1:\n\t" | 127 | "1:\n\t" |
@@ -126,6 +129,9 @@ static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int siz | |||
126 | "jne 1b" | 129 | "jne 1b" |
127 | : "=&d" (x) : "d" (x), "m" (*__xg(ptr)) : "memory"); | 130 | : "=&d" (x) : "d" (x), "m" (*__xg(ptr)) : "memory"); |
128 | break; | 131 | break; |
132 | default: | ||
133 | x = __invalid_xchg_size(x, ptr, size); | ||
134 | break; | ||
129 | } | 135 | } |
130 | return x; | 136 | return x; |
131 | } | 137 | } |
@@ -135,6 +141,9 @@ static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int siz | |||
135 | 141 | ||
136 | #define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n)) | 142 | #define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n)) |
137 | 143 | ||
144 | extern unsigned long __invalid_cmpxchg_size(volatile void *, | ||
145 | unsigned long, unsigned long, int); | ||
146 | |||
138 | /* | 147 | /* |
139 | * Atomic compare and exchange. Compare OLD with MEM, if identical, | 148 | * Atomic compare and exchange. Compare OLD with MEM, if identical, |
140 | * store NEW in MEM. Return the initial value in MEM. Success is | 149 | * store NEW in MEM. Return the initial value in MEM. Success is |
@@ -162,6 +171,9 @@ static inline unsigned long __cmpxchg(volatile void *p, unsigned long old, | |||
162 | : "=d" (old), "=m" (*(int *)p) | 171 | : "=d" (old), "=m" (*(int *)p) |
163 | : "d" (new), "0" (old), "m" (*(int *)p)); | 172 | : "d" (new), "0" (old), "m" (*(int *)p)); |
164 | break; | 173 | break; |
174 | default: | ||
175 | old = __invalid_cmpxchg_size(p, old, new, size); | ||
176 | break; | ||
165 | } | 177 | } |
166 | return old; | 178 | return old; |
167 | } | 179 | } |