1 /* MN10300 Atomic xchg/cmpxchg operations
3 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public Licence
8 * as published by the Free Software Foundation; either version
9 * 2 of the Licence, or (at your option) any later version.
11 #ifndef _ASM_CMPXCHG_H
12 #define _ASM_CMPXCHG_H
14 #include <asm/irqflags.h>
17 #ifdef CONFIG_MN10300_HAS_ATOMIC_OPS_UNIT
19 unsigned long __xchg(volatile unsigned long *m
, unsigned long val
)
25 "1: mov %4,(_AAR,%3) \n"
26 " mov (_ADR,%3),%1 \n"
27 " mov %5,(_ADR,%3) \n"
28 " mov (_ADR,%3),%0 \n" /* flush */
29 " mov (_ASR,%3),%0 \n"
32 : "=&r"(status
), "=&r"(oldval
), "=m"(*m
)
33 : "a"(ATOMIC_OPS_BASE_ADDR
), "r"(m
), "r"(val
)
39 static inline unsigned long __cmpxchg(volatile unsigned long *m
,
40 unsigned long old
, unsigned long new)
46 "1: mov %4,(_AAR,%3) \n"
47 " mov (_ADR,%3),%1 \n"
50 " mov %6,(_ADR,%3) \n"
51 "2: mov (_ADR,%3),%0 \n" /* flush */
52 " mov (_ASR,%3),%0 \n"
55 : "=&r"(status
), "=&r"(oldval
), "=m"(*m
)
56 : "a"(ATOMIC_OPS_BASE_ADDR
), "r"(m
),
62 #else /* CONFIG_MN10300_HAS_ATOMIC_OPS_UNIT */
63 #error "No SMP atomic operation support!"
64 #endif /* CONFIG_MN10300_HAS_ATOMIC_OPS_UNIT */
66 #else /* CONFIG_SMP */
69 * Emulate xchg for non-SMP MN10300
71 struct __xchg_dummy
{ unsigned long a
[100]; };
72 #define __xg(x) ((struct __xchg_dummy *)(x))
75 unsigned long __xchg(volatile unsigned long *m
, unsigned long val
)
80 flags
= arch_local_cli_save();
83 arch_local_irq_restore(flags
);
88 * Emulate cmpxchg for non-SMP MN10300
90 static inline unsigned long __cmpxchg(volatile unsigned long *m
,
91 unsigned long old
, unsigned long new)
96 flags
= arch_local_cli_save();
100 arch_local_irq_restore(flags
);
104 #endif /* CONFIG_SMP */
106 #define xchg(ptr, v) \
107 ((__typeof__(*(ptr))) __xchg((unsigned long *)(ptr), \
110 #define cmpxchg(ptr, o, n) \
111 ((__typeof__(*(ptr))) __cmpxchg((unsigned long *)(ptr), \
112 (unsigned long)(o), \
115 #endif /* _ASM_CMPXCHG_H */