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