12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061 |
- /*
- * Atomics xchg/cmpxchg for PKUnity SoC and UniCore ISA
- *
- * Copyright (C) 2001-2012 GUAN Xue-tao
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
- #ifndef __UNICORE_CMPXCHG_H__
- #define __UNICORE_CMPXCHG_H__
- /*
- * Generate a link failure on undefined symbol if the pointer points to a value
- * of unsupported size.
- */
- extern void __xchg_bad_pointer(void);
- static inline unsigned long __xchg(unsigned long x, volatile void *ptr,
- int size)
- {
- unsigned long ret;
- switch (size) {
- case 1:
- asm volatile("swapb %0, %1, [%2]"
- : "=&r" (ret)
- : "r" (x), "r" (ptr)
- : "memory", "cc");
- break;
- case 4:
- asm volatile("swapw %0, %1, [%2]"
- : "=&r" (ret)
- : "r" (x), "r" (ptr)
- : "memory", "cc");
- break;
- default:
- __xchg_bad_pointer();
- }
- return ret;
- }
- #define xchg(ptr, x) \
- ((__typeof__(*(ptr)))__xchg((unsigned long)(x), (ptr), sizeof(*(ptr))))
- #include <asm-generic/cmpxchg-local.h>
- /*
- * cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make
- * them available.
- */
- #define cmpxchg_local(ptr, o, n) \
- ((__typeof__(*(ptr)))__cmpxchg_local_generic((ptr), \
- (unsigned long)(o), (unsigned long)(n), sizeof(*(ptr))))
- #define cmpxchg64_local(ptr, o, n) \
- __cmpxchg64_local_generic((ptr), (o), (n))
- #include <asm-generic/cmpxchg.h>
- #endif /* __UNICORE_CMPXCHG_H__ */
|