• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/components/opensource/linux/linux-2.6.36/arch/mips/include/asm/pmc-sierra/msp71xx/
1
2
3#ifndef __ASM_REGOPS_H__
4#define __ASM_REGOPS_H__
5
6#include <linux/types.h>
7
8#include <asm/war.h>
9
10#ifndef R10000_LLSC_WAR
11#define R10000_LLSC_WAR 0
12#endif
13
14#if R10000_LLSC_WAR == 1
15#define __beqz	"beqzl	"
16#else
17#define __beqz	"beqz	"
18#endif
19
20#ifndef _LINUX_TYPES_H
21typedef unsigned int u32;
22#endif
23
24/*
25 * Sets all the masked bits to the corresponding value bits
26 */
27static inline void set_value_reg32(volatile u32 *const addr,
28					u32 const mask,
29					u32 const value)
30{
31	u32 temp;
32
33	__asm__ __volatile__(
34	"	.set	push				\n"
35	"	.set	mips3				\n"
36	"1:	ll	%0, %1	# set_value_reg32	\n"
37	"	and	%0, %2				\n"
38	"	or	%0, %3				\n"
39	"	sc	%0, %1				\n"
40	"	"__beqz"%0, 1b				\n"
41	"	nop					\n"
42	"	.set	pop				\n"
43	: "=&r" (temp), "=m" (*addr)
44	: "ir" (~mask), "ir" (value), "m" (*addr));
45}
46
47/*
48 * Sets all the masked bits to '1'
49 */
50static inline void set_reg32(volatile u32 *const addr,
51				u32 const mask)
52{
53	u32 temp;
54
55	__asm__ __volatile__(
56	"	.set	push				\n"
57	"	.set	mips3				\n"
58	"1:	ll	%0, %1		# set_reg32	\n"
59	"	or	%0, %2				\n"
60	"	sc	%0, %1				\n"
61	"	"__beqz"%0, 1b				\n"
62	"	nop					\n"
63	"	.set	pop				\n"
64	: "=&r" (temp), "=m" (*addr)
65	: "ir" (mask), "m" (*addr));
66}
67
68/*
69 * Sets all the masked bits to '0'
70 */
71static inline void clear_reg32(volatile u32 *const addr,
72				u32 const mask)
73{
74	u32 temp;
75
76	__asm__ __volatile__(
77	"	.set	push				\n"
78	"	.set	mips3				\n"
79	"1:	ll	%0, %1		# clear_reg32	\n"
80	"	and	%0, %2				\n"
81	"	sc	%0, %1				\n"
82	"	"__beqz"%0, 1b				\n"
83	"	nop					\n"
84	"	.set	pop				\n"
85	: "=&r" (temp), "=m" (*addr)
86	: "ir" (~mask), "m" (*addr));
87}
88
89/*
90 * Toggles all masked bits from '0' to '1' and '1' to '0'
91 */
92static inline void toggle_reg32(volatile u32 *const addr,
93				u32 const mask)
94{
95	u32 temp;
96
97	__asm__ __volatile__(
98	"	.set	push				\n"
99	"	.set	mips3				\n"
100	"1:	ll	%0, %1		# toggle_reg32	\n"
101	"	xor	%0, %2				\n"
102	"	sc	%0, %1				\n"
103	"	"__beqz"%0, 1b				\n"
104	"	nop					\n"
105	"	.set	pop				\n"
106	: "=&r" (temp), "=m" (*addr)
107	: "ir" (mask), "m" (*addr));
108}
109
110/*
111 * Read all masked bits others are returned as '0'
112 */
113static inline u32 read_reg32(volatile u32 *const addr,
114				u32 const mask)
115{
116	u32 temp;
117
118	__asm__ __volatile__(
119	"	.set	push				\n"
120	"	.set	noreorder			\n"
121	"	lw	%0, %1		# read		\n"
122	"	and	%0, %2		# mask		\n"
123	"	.set	pop				\n"
124	: "=&r" (temp)
125	: "m" (*addr), "ir" (mask));
126
127	return temp;
128}
129
130/*
131 * blocking_read_reg32 - Read address with blocking load
132 *
133 * Uncached writes need to be read back to ensure they reach RAM.
134 * The returned value must be 'used' to prevent from becoming a
135 * non-blocking load.
136 */
137static inline u32 blocking_read_reg32(volatile u32 *const addr)
138{
139	u32 temp;
140
141	__asm__ __volatile__(
142	"	.set	push				\n"
143	"	.set	noreorder			\n"
144	"	lw	%0, %1		# read		\n"
145	"	move	%0, %0		# block		\n"
146	"	.set	pop				\n"
147	: "=&r" (temp)
148	: "m" (*addr));
149
150	return temp;
151}
152
153/*
154 * For special strange cases only:
155 *
156 * If you need custom processing within a ll/sc loop, use the following macros
157 * VERY CAREFULLY:
158 *
159 *   u32 tmp;				<-- Define a variable to hold the data
160 *
161 *   custom_read_reg32(address, tmp);	<-- Reads the address and put the value
162 *						in the 'tmp' variable given
163 *
164 *	From here on out, you are (basicly) atomic, so don't do anything too
165 *	fancy!
166 *	Also, this code may loop if the end of this block fails to write
167 *	everything back safely due do the other CPU, so do NOT do anything
168 *	with side-effects!
169 *
170 *   custom_write_reg32(address, tmp);	<-- Writes back 'tmp' safely.
171 */
172#define custom_read_reg32(address, tmp)				\
173	__asm__ __volatile__(					\
174	"	.set	push				\n"	\
175	"	.set	mips3				\n"	\
176	"1:	ll	%0, %1	#custom_read_reg32	\n"	\
177	"	.set	pop				\n"	\
178	: "=r" (tmp), "=m" (*address)				\
179	: "m" (*address))
180
181#define custom_write_reg32(address, tmp)			\
182	__asm__ __volatile__(					\
183	"	.set	push				\n"	\
184	"	.set	mips3				\n"	\
185	"	sc	%0, %1	#custom_write_reg32	\n"	\
186	"	"__beqz"%0, 1b				\n"	\
187	"	nop					\n"	\
188	"	.set	pop				\n"	\
189	: "=&r" (tmp), "=m" (*address)				\
190	: "0" (tmp), "m" (*address))
191
192#endif  /* __ASM_REGOPS_H__ */
193