1/*
2 * Copyright (C) 2004 Microtronix Datacom Ltd.
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 */
8
9#ifndef _ASM_NIOS2_CMPXCHG_H
10#define _ASM_NIOS2_CMPXCHG_H
11
12#include <linux/irqflags.h>
13
14#define xchg(ptr, x)	\
15	((__typeof__(*(ptr)))__xchg((unsigned long)(x), (ptr), sizeof(*(ptr))))
16
17struct __xchg_dummy { unsigned long a[100]; };
18#define __xg(x)		((volatile struct __xchg_dummy *)(x))
19
20static inline unsigned long __xchg(unsigned long x, volatile void *ptr,
21					int size)
22{
23	unsigned long tmp, flags;
24
25	local_irq_save(flags);
26
27	switch (size) {
28	case 1:
29		__asm__ __volatile__(
30			"ldb	%0, %2\n"
31			"stb	%1, %2\n"
32			: "=&r" (tmp)
33			: "r" (x), "m" (*__xg(ptr))
34			: "memory");
35		break;
36	case 2:
37		__asm__ __volatile__(
38			"ldh	%0, %2\n"
39			"sth	%1, %2\n"
40			: "=&r" (tmp)
41			: "r" (x), "m" (*__xg(ptr))
42			: "memory");
43		break;
44	case 4:
45		__asm__ __volatile__(
46			"ldw	%0, %2\n"
47			"stw	%1, %2\n"
48			: "=&r" (tmp)
49			: "r" (x), "m" (*__xg(ptr))
50			: "memory");
51		break;
52	}
53
54	local_irq_restore(flags);
55	return tmp;
56}
57
58#include <asm-generic/cmpxchg.h>
59#include <asm-generic/cmpxchg-local.h>
60
61#endif /* _ASM_NIOS2_CMPXCHG_H */
62