Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
arch
mn10300
include
asm
cmpxchg.h
Go to the documentation of this file.
1
/* MN10300 Atomic xchg/cmpxchg operations
2
*
3
* Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
4
* Written by David Howells (
[email protected]
)
5
*
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.
10
*/
11
#ifndef _ASM_CMPXCHG_H
12
#define _ASM_CMPXCHG_H
13
14
#include <asm/irqflags.h>
15
16
#ifdef CONFIG_SMP
17
#ifdef CONFIG_MN10300_HAS_ATOMIC_OPS_UNIT
18
static
inline
19
unsigned
long
__xchg
(
volatile
unsigned
long
*
m
,
unsigned
long
val
)
20
{
21
unsigned
long
status
;
22
unsigned
long
oldval;
23
24
asm
volatile
(
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"
30
" or %0,%0 \n"
31
" bne 1b \n"
32
:
"=&r"
(
status
),
"=&r"
(oldval),
"=m"
(*m)
33
:
"a"
(ATOMIC_OPS_BASE_ADDR),
"r"
(m),
"r"
(
val
)
34
:
"memory"
,
"cc"
);
35
36
return
oldval;
37
}
38
39
static
inline
unsigned
long
__cmpxchg
(
volatile
unsigned
long
*m,
40
unsigned
long
old,
unsigned
long
new
)
41
{
42
unsigned
long
status
;
43
unsigned
long
oldval;
44
45
asm
volatile
(
46
"1: mov %4,(_AAR,%3) \n"
47
" mov (_ADR,%3),%1 \n"
48
" cmp %5,%1 \n"
49
" bne 2f \n"
50
" mov %6,(_ADR,%3) \n"
51
"2: mov (_ADR,%3),%0 \n"
/* flush */
52
" mov (_ASR,%3),%0 \n"
53
" or %0,%0 \n"
54
" bne 1b \n"
55
:
"=&r"
(
status
),
"=&r"
(oldval),
"=m"
(*m)
56
:
"a"
(ATOMIC_OPS_BASE_ADDR),
"r"
(m),
57
"r"
(old),
"r"
(
new
)
58
:
"memory"
,
"cc"
);
59
60
return
oldval;
61
}
62
#else
/* CONFIG_MN10300_HAS_ATOMIC_OPS_UNIT */
63
#error "No SMP atomic operation support!"
64
#endif
/* CONFIG_MN10300_HAS_ATOMIC_OPS_UNIT */
65
66
#else
/* CONFIG_SMP */
67
68
/*
69
* Emulate xchg for non-SMP MN10300
70
*/
71
struct
__xchg_dummy
{
unsigned
long
a
[100]; };
72
#define __xg(x) ((struct __xchg_dummy *)(x))
73
74
static
inline
75
unsigned
long
__xchg
(
volatile
unsigned
long
*m,
unsigned
long
val)
76
{
77
unsigned
long
oldval;
78
unsigned
long
flags
;
79
80
flags = arch_local_cli_save();
81
oldval = *
m
;
82
*m =
val
;
83
arch_local_irq_restore
(flags);
84
return
oldval;
85
}
86
87
/*
88
* Emulate cmpxchg for non-SMP MN10300
89
*/
90
static
inline
unsigned
long
__cmpxchg
(
volatile
unsigned
long
*m,
91
unsigned
long
old,
unsigned
long
new
)
92
{
93
unsigned
long
oldval;
94
unsigned
long
flags
;
95
96
flags = arch_local_cli_save();
97
oldval = *
m
;
98
if
(oldval == old)
99
*m =
new
;
100
arch_local_irq_restore
(flags);
101
return
oldval;
102
}
103
104
#endif
/* CONFIG_SMP */
105
106
#define xchg(ptr, v) \
107
((__typeof__(*(ptr))) __xchg((unsigned long *)(ptr), \
108
(unsigned long)(v)))
109
110
#define cmpxchg(ptr, o, n) \
111
((__typeof__(*(ptr))) __cmpxchg((unsigned long *)(ptr), \
112
(unsigned long)(o), \
113
(unsigned long)(n)))
114
115
#endif
/* _ASM_CMPXCHG_H */
Generated on Thu Jan 10 2013 12:49:17 for Linux Kernel by
1.8.2