Loading...
Note: File does not exist in v6.2.
1/*
2 * cmpxchg.h -- forked from asm/atomic.h with this copyright:
3 *
4 * Copyright 2010 Tilera Corporation. All Rights Reserved.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation, version 2.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
13 * NON INFRINGEMENT. See the GNU General Public License for
14 * more details.
15 *
16 */
17
18#ifndef _ASM_TILE_CMPXCHG_H
19#define _ASM_TILE_CMPXCHG_H
20
21#ifndef __ASSEMBLY__
22
23#include <asm/barrier.h>
24
25/* Nonexistent functions intended to cause compile errors. */
26extern void __xchg_called_with_bad_pointer(void)
27 __compiletime_error("Bad argument size for xchg");
28extern void __cmpxchg_called_with_bad_pointer(void)
29 __compiletime_error("Bad argument size for cmpxchg");
30
31#ifndef __tilegx__
32
33/* Note the _atomic_xxx() routines include a final mb(). */
34int _atomic_xchg(int *ptr, int n);
35int _atomic_xchg_add(int *v, int i);
36int _atomic_xchg_add_unless(int *v, int a, int u);
37int _atomic_cmpxchg(int *ptr, int o, int n);
38long long _atomic64_xchg(long long *v, long long n);
39long long _atomic64_xchg_add(long long *v, long long i);
40long long _atomic64_xchg_add_unless(long long *v, long long a, long long u);
41long long _atomic64_cmpxchg(long long *v, long long o, long long n);
42
43#define xchg(ptr, n) \
44 ({ \
45 if (sizeof(*(ptr)) != 4) \
46 __xchg_called_with_bad_pointer(); \
47 smp_mb(); \
48 (typeof(*(ptr)))_atomic_xchg((int *)(ptr), (int)(n)); \
49 })
50
51#define cmpxchg(ptr, o, n) \
52 ({ \
53 if (sizeof(*(ptr)) != 4) \
54 __cmpxchg_called_with_bad_pointer(); \
55 smp_mb(); \
56 (typeof(*(ptr)))_atomic_cmpxchg((int *)ptr, (int)o, \
57 (int)n); \
58 })
59
60#define xchg64(ptr, n) \
61 ({ \
62 if (sizeof(*(ptr)) != 8) \
63 __xchg_called_with_bad_pointer(); \
64 smp_mb(); \
65 (typeof(*(ptr)))_atomic64_xchg((long long *)(ptr), \
66 (long long)(n)); \
67 })
68
69#define cmpxchg64(ptr, o, n) \
70 ({ \
71 if (sizeof(*(ptr)) != 8) \
72 __cmpxchg_called_with_bad_pointer(); \
73 smp_mb(); \
74 (typeof(*(ptr)))_atomic64_cmpxchg((long long *)ptr, \
75 (long long)o, (long long)n); \
76 })
77
78#else
79
80#define xchg(ptr, n) \
81 ({ \
82 typeof(*(ptr)) __x; \
83 smp_mb(); \
84 switch (sizeof(*(ptr))) { \
85 case 4: \
86 __x = (typeof(__x))(unsigned long) \
87 __insn_exch4((ptr), \
88 (u32)(unsigned long)(n)); \
89 break; \
90 case 8: \
91 __x = (typeof(__x)) \
92 __insn_exch((ptr), (unsigned long)(n)); \
93 break; \
94 default: \
95 __xchg_called_with_bad_pointer(); \
96 break; \
97 } \
98 smp_mb(); \
99 __x; \
100 })
101
102#define cmpxchg(ptr, o, n) \
103 ({ \
104 typeof(*(ptr)) __x; \
105 __insn_mtspr(SPR_CMPEXCH_VALUE, (unsigned long)(o)); \
106 smp_mb(); \
107 switch (sizeof(*(ptr))) { \
108 case 4: \
109 __x = (typeof(__x))(unsigned long) \
110 __insn_cmpexch4((ptr), \
111 (u32)(unsigned long)(n)); \
112 break; \
113 case 8: \
114 __x = (typeof(__x))__insn_cmpexch((ptr), \
115 (long long)(n)); \
116 break; \
117 default: \
118 __cmpxchg_called_with_bad_pointer(); \
119 break; \
120 } \
121 smp_mb(); \
122 __x; \
123 })
124
125#define xchg64 xchg
126#define cmpxchg64 cmpxchg
127
128#endif
129
130#endif /* __ASSEMBLY__ */
131
132#endif /* _ASM_TILE_CMPXCHG_H */