1#ifndef __ASM_CRIS_CMPXCHG__ 2#define __ASM_CRIS_CMPXCHG__ 3 4#include <linux/irqflags.h> 5 6static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size) 7{ 8 /* since Etrax doesn't have any atomic xchg instructions, we need to disable 9 irq's (if enabled) and do it with move.d's */ 10 unsigned long flags,temp; 11 local_irq_save(flags); /* save flags, including irq enable bit and shut off irqs */ 12 switch (size) { 13 case 1: 14 *((unsigned char *)&temp) = x; 15 x = *(unsigned char *)ptr; 16 *(unsigned char *)ptr = *((unsigned char *)&temp); 17 break; 18 case 2: 19 *((unsigned short *)&temp) = x; 20 x = *(unsigned short *)ptr; 21 *(unsigned short *)ptr = *((unsigned short *)&temp); 22 break; 23 case 4: 24 temp = x; 25 x = *(unsigned long *)ptr; 26 *(unsigned long *)ptr = temp; 27 break; 28 } 29 local_irq_restore(flags); /* restore irq enable bit */ 30 return x; 31} 32 33#define xchg(ptr,x) \ 34 ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr)))) 35 36#define tas(ptr) (xchg((ptr),1)) 37 38#include <asm-generic/cmpxchg-local.h> 39 40/* 41 * cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make 42 * them available. 43 */ 44#define cmpxchg_local(ptr, o, n) \ 45 ((__typeof__(*(ptr)))__cmpxchg_local_generic((ptr), (unsigned long)(o),\ 46 (unsigned long)(n), sizeof(*(ptr)))) 47#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n)) 48 49#ifndef CONFIG_SMP 50#include <asm-generic/cmpxchg.h> 51#endif 52 53#endif /* __ASM_CRIS_CMPXCHG__ */ 54