Merge ../linus
[linux-2.6] / include / asm-arm / arch-cl7500 / io.h
1 /*
2  * linux/include/asm-arm/arch-cl7500/io.h
3  *  from linux/include/asm-arm/arch-rpc/io.h
4  *
5  * Copyright (C) 1997 Russell King
6  *
7  * Modifications:
8  *  06-Dec-1997 RMK     Created.
9  */
10 #ifndef __ASM_ARM_ARCH_IO_H
11 #define __ASM_ARM_ARCH_IO_H
12
13 #include <asm/hardware.h>
14
15 #define IO_SPACE_LIMIT 0xffffffff
16
17 /*
18  * GCC is totally crap at loading/storing data.  We try to persuade it
19  * to do the right thing by using these whereever possible instead of
20  * the above.
21  */
22 #define __arch_base_getb(b,o)                   \
23  ({                                             \
24         unsigned int v, r = (b);                \
25         __asm__ __volatile__(                   \
26                 "ldrb   %0, [%1, %2]"           \
27                 : "=r" (v)                      \
28                 : "r" (r), "Ir" (o));           \
29         v;                                      \
30  })
31
32 #define __arch_base_getl(b,o)                   \
33  ({                                             \
34         unsigned int v, r = (b);                \
35         __asm__ __volatile__(                   \
36                 "ldr    %0, [%1, %2]"           \
37                 : "=r" (v)                      \
38                 : "r" (r), "Ir" (o));           \
39         v;                                      \
40  })
41
42 #define __arch_base_putb(v,b,o)                 \
43  ({                                             \
44         unsigned int r = (b);                   \
45         __asm__ __volatile__(                   \
46                 "strb   %0, [%1, %2]"           \
47                 :                               \
48                 : "r" (v), "r" (r), "Ir" (o));  \
49  })
50
51 #define __arch_base_putl(v,b,o)                 \
52  ({                                             \
53         unsigned int r = (b);                   \
54         __asm__ __volatile__(                   \
55                 "str    %0, [%1, %2]"           \
56                 :                               \
57                 : "r" (v), "r" (r), "Ir" (o));  \
58  })
59
60 /*
61  * We use two different types of addressing - PC style addresses, and ARM
62  * addresses.  PC style accesses the PC hardware with the normal PC IO
63  * addresses, eg 0x3f8 for serial#1.  ARM addresses are 0x80000000+
64  * and are translated to the start of IO.  Note that all addresses are
65  * shifted left!
66  */
67 #define __PORT_PCIO(x)  (!((x) & 0x80000000))
68
69 /*
70  * Dynamic IO functions - let the compiler
71  * optimize the expressions
72  */
73 static inline void __outb (unsigned int value, unsigned int port)
74 {
75         unsigned long temp;
76         __asm__ __volatile__(
77         "tst    %2, #0x80000000\n\t"
78         "mov    %0, %4\n\t"
79         "addeq  %0, %0, %3\n\t"
80         "strb   %1, [%0, %2, lsl #2]    @ outb"
81         : "=&r" (temp)
82         : "r" (value), "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE)
83         : "cc");
84 }
85
86 static inline void __outw (unsigned int value, unsigned int port)
87 {
88         unsigned long temp;
89         __asm__ __volatile__(
90         "tst    %2, #0x80000000\n\t"
91         "mov    %0, %4\n\t"
92         "addeq  %0, %0, %3\n\t"
93         "str    %1, [%0, %2, lsl #2]    @ outw"
94         : "=&r" (temp)
95         : "r" (value|value<<16), "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE)
96         : "cc");
97 }
98
99 static inline void __outl (unsigned int value, unsigned int port)
100 {
101         unsigned long temp;
102         __asm__ __volatile__(
103         "tst    %2, #0x80000000\n\t"
104         "mov    %0, %4\n\t"
105         "addeq  %0, %0, %3\n\t"
106         "str    %1, [%0, %2, lsl #2]    @ outl"
107         : "=&r" (temp)
108         : "r" (value), "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE)
109         : "cc");
110 }
111
112 #define DECLARE_DYN_IN(sz,fnsuffix,instr)                                       \
113 static inline unsigned sz __in##fnsuffix (unsigned int port)            \
114 {                                                                               \
115         unsigned long temp, value;                                              \
116         __asm__ __volatile__(                                                   \
117         "tst    %2, #0x80000000\n\t"                                            \
118         "mov    %0, %4\n\t"                                                     \
119         "addeq  %0, %0, %3\n\t"                                                 \
120         "ldr" instr "   %1, [%0, %2, lsl #2]    @ in" #fnsuffix                 \
121         : "=&r" (temp), "=r" (value)                                            \
122         : "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE)                \
123         : "cc");                                                                \
124         return (unsigned sz)value;                                              \
125 }
126
127 static inline unsigned int __ioaddr (unsigned int port)                 \
128 {                                                                               \
129         if (__PORT_PCIO(port))                                                  \
130                 return (unsigned int)(PCIO_BASE + (port << 2));                 \
131         else                                                                    \
132                 return (unsigned int)(IO_BASE + (port << 2));                   \
133 }
134
135 #define DECLARE_IO(sz,fnsuffix,instr)   \
136         DECLARE_DYN_IN(sz,fnsuffix,instr)
137
138 DECLARE_IO(char,b,"b")
139 DECLARE_IO(short,w,"")
140 DECLARE_IO(int,l,"")
141
142 #undef DECLARE_IO
143 #undef DECLARE_DYN_IN
144
145 /*
146  * Constant address IO functions
147  *
148  * These have to be macros for the 'J' constraint to work -
149  * +/-4096 immediate operand.
150  */
151 #define __outbc(value,port)                                                     \
152 ({                                                                              \
153         if (__PORT_PCIO((port)))                                                \
154                 __asm__ __volatile__(                                           \
155                 "strb   %0, [%1, %2]    @ outbc"                                \
156                 : : "r" (value), "r" (PCIO_BASE), "Jr" ((port) << 2));          \
157         else                                                                    \
158                 __asm__ __volatile__(                                           \
159                 "strb   %0, [%1, %2]    @ outbc"                                \
160                 : : "r" (value), "r" (IO_BASE), "r" ((port) << 2));             \
161 })
162
163 #define __inbc(port)                                                            \
164 ({                                                                              \
165         unsigned char result;                                                   \
166         if (__PORT_PCIO((port)))                                                \
167                 __asm__ __volatile__(                                           \
168                 "ldrb   %0, [%1, %2]    @ inbc"                                 \
169                 : "=r" (result) : "r" (PCIO_BASE), "Jr" ((port) << 2));         \
170         else                                                                    \
171                 __asm__ __volatile__(                                           \
172                 "ldrb   %0, [%1, %2]    @ inbc"                                 \
173                 : "=r" (result) : "r" (IO_BASE), "r" ((port) << 2));            \
174         result;                                                                 \
175 })
176
177 #define __outwc(value,port)                                                     \
178 ({                                                                              \
179         unsigned long v = value;                                                \
180         if (__PORT_PCIO((port)))                                                \
181                 __asm__ __volatile__(                                           \
182                 "str    %0, [%1, %2]    @ outwc"                                \
183                 : : "r" (v|v<<16), "r" (PCIO_BASE), "Jr" ((port) << 2));        \
184         else                                                                    \
185                 __asm__ __volatile__(                                           \
186                 "str    %0, [%1, %2]    @ outwc"                                \
187                 : : "r" (v|v<<16), "r" (IO_BASE), "r" ((port) << 2));           \
188 })
189
190 #define __inwc(port)                                                            \
191 ({                                                                              \
192         unsigned short result;                                                  \
193         if (__PORT_PCIO((port)))                                                \
194                 __asm__ __volatile__(                                           \
195                 "ldr    %0, [%1, %2]    @ inwc"                                 \
196                 : "=r" (result) : "r" (PCIO_BASE), "Jr" ((port) << 2));         \
197         else                                                                    \
198                 __asm__ __volatile__(                                           \
199                 "ldr    %0, [%1, %2]    @ inwc"                                 \
200                 : "=r" (result) : "r" (IO_BASE), "r" ((port) << 2));            \
201         result & 0xffff;                                                        \
202 })
203
204 #define __outlc(value,port)                                                     \
205 ({                                                                              \
206         unsigned long v = value;                                                \
207         if (__PORT_PCIO((port)))                                                \
208                 __asm__ __volatile__(                                           \
209                 "str    %0, [%1, %2]    @ outlc"                                \
210                 : : "r" (v), "r" (PCIO_BASE), "Jr" ((port) << 2));              \
211         else                                                                    \
212                 __asm__ __volatile__(                                           \
213                 "str    %0, [%1, %2]    @ outlc"                                \
214                 : : "r" (v), "r" (IO_BASE), "r" ((port) << 2));                 \
215 })
216
217 #define __inlc(port)                                                            \
218 ({                                                                              \
219         unsigned long result;                                                   \
220         if (__PORT_PCIO((port)))                                                \
221                 __asm__ __volatile__(                                           \
222                 "ldr    %0, [%1, %2]    @ inlc"                                 \
223                 : "=r" (result) : "r" (PCIO_BASE), "Jr" ((port) << 2));         \
224         else                                                                    \
225                 __asm__ __volatile__(                                           \
226                 "ldr    %0, [%1, %2]    @ inlc"                                 \
227                 : "=r" (result) : "r" (IO_BASE), "r" ((port) << 2));            \
228         result;                                                                 \
229 })
230
231 #define __ioaddrc(port)                                                         \
232         (__PORT_PCIO((port)) ? PCIO_BASE + ((port) << 2) : IO_BASE + ((port) << 2))
233
234 #define inb(p)          (__builtin_constant_p((p)) ? __inbc(p)    : __inb(p))
235 #define inw(p)          (__builtin_constant_p((p)) ? __inwc(p)    : __inw(p))
236 #define inl(p)          (__builtin_constant_p((p)) ? __inlc(p)    : __inl(p))
237 #define outb(v,p)       (__builtin_constant_p((p)) ? __outbc(v,p) : __outb(v,p))
238 #define outw(v,p)       (__builtin_constant_p((p)) ? __outwc(v,p) : __outw(v,p))
239 #define outl(v,p)       (__builtin_constant_p((p)) ? __outlc(v,p) : __outl(v,p))
240 #define __ioaddr(p)     (__builtin_constant_p((p)) ? __ioaddr(p)  : __ioaddrc(p))
241 /* the following macro is deprecated */
242 #define ioaddr(port)                    __ioaddr((port))
243
244 #define insb(p,d,l)     __raw_readsb(__ioaddr(p),d,l)
245 #define insw(p,d,l)     __raw_readsw(__ioaddr(p),d,l)
246
247 #define outsb(p,d,l)    __raw_writesb(__ioaddr(p),d,l)
248 #define outsw(p,d,l)    __raw_writesw(__ioaddr(p),d,l)
249
250 /*
251  * 1:1 mapping for ioremapped regions.
252  */
253 #define __mem_pci(x)    (x)
254
255 #endif