1/* 2 * Atomics xchg/cmpxchg for PKUnity SoC and UniCore ISA 3 * 4 * Copyright (C) 2001-2012 GUAN Xue-tao 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 2 as 8 * published by the Free Software Foundation. 9 */ 10#ifndef __UNICORE_CMPXCHG_H__ 11#define __UNICORE_CMPXCHG_H__ 12 13/* 14 * Generate a link failure on undefined symbol if the pointer points to a value 15 * of unsupported size. 16 */ 17extern void __xchg_bad_pointer(void); 18 19static inline unsigned long __xchg(unsigned long x, volatile void *ptr, 20 int size) 21{ 22 unsigned long ret; 23 24 switch (size) { 25 case 1: 26 asm volatile("swapb %0, %1, [%2]" 27 : "=&r" (ret) 28 : "r" (x), "r" (ptr) 29 : "memory", "cc"); 30 break; 31 case 4: 32 asm volatile("swapw %0, %1, [%2]" 33 : "=&r" (ret) 34 : "r" (x), "r" (ptr) 35 : "memory", "cc"); 36 break; 37 default: 38 __xchg_bad_pointer(); 39 } 40 41 return ret; 42} 43 44#define xchg(ptr, x) \ 45 ((__typeof__(*(ptr)))__xchg((unsigned long)(x), (ptr), sizeof(*(ptr)))) 46 47#include <asm-generic/cmpxchg-local.h> 48 49/* 50 * cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make 51 * them available. 52 */ 53#define cmpxchg_local(ptr, o, n) \ 54 ((__typeof__(*(ptr)))__cmpxchg_local_generic((ptr), \ 55 (unsigned long)(o), (unsigned long)(n), sizeof(*(ptr)))) 56#define cmpxchg64_local(ptr, o, n) \ 57 __cmpxchg64_local_generic((ptr), (o), (n)) 58 59#include <asm-generic/cmpxchg.h> 60 61#endif /* __UNICORE_CMPXCHG_H__ */ 62