aboutsummaryrefslogtreecommitdiffstats
path: root/arch/m68k
diff options
context:
space:
mode:
Diffstat (limited to 'arch/m68k')
-rw-r--r--arch/m68k/include/asm/system.h20
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);
68struct __xchg_dummy { unsigned long a[100]; }; 68struct __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
71extern unsigned long __invalid_xchg_size(unsigned long, volatile void *, int);
72
71#ifndef CONFIG_RMW_INSNS 73#ifndef CONFIG_RMW_INSNS
72static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size) 74static 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
102static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size) 105static 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
144extern 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}