ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / include / asm-arm / arch-s3c2410 / io.h
1 /*
2  * linux/include/asm-arm/arch-s3c2410/io.h
3  *  from linux/include/asm-arm/arch-rpc/io.h
4  *
5  * Copyright (C) 1997 Russell King
6  *           (C) 2003 Simtec Electronics
7  *
8  * Modifications:
9  *  06-Dec-1997 RMK     Created.
10  *  02-Sep-2003 BJD     Modified for S3C2410
11  *
12  */
13
14 #ifndef __ASM_ARM_ARCH_IO_H
15 #define __ASM_ARM_ARCH_IO_H
16
17 #define IO_SPACE_LIMIT 0xffffffff
18
19 /*
20  * We use two different types of addressing - PC style addresses, and ARM
21  * addresses.  PC style accesses the PC hardware with the normal PC IO
22  * addresses, eg 0x3f8 for serial#1.  ARM addresses are above A28
23  * and are translated to the start of IO.  Note that all addresses are
24  * not shifted left!
25  */
26
27 #define __PORT_PCIO(x)  ((x) < (1<<28))
28
29 #define PCIO_BASE        (S3C2410_VA_ISA_WORD)
30 #define PCIO_BASE_b      (S3C2410_VA_ISA_BYTE)
31 #define PCIO_BASE_w      (S3C2410_VA_ISA_WORD)
32 #define PCIO_BASE_l      (S3C2410_VA_ISA_WORD)
33 /*
34  * Dynamic IO functions - let the compiler
35  * optimize the expressions
36  */
37
38 #define DECLARE_DYN_OUT(sz,fnsuffix,instr) \
39 static inline void __out##fnsuffix (unsigned int val, unsigned int port) \
40 { \
41         unsigned long temp;                                   \
42         __asm__ __volatile__(                                 \
43         "cmp    %2, #(1<<28)\n\t"                             \
44         "mov    %0, %2\n\t"                                   \
45         "addcc  %0, %0, %3\n\t"                               \
46         "str" instr " %1, [%0, #0 ]     @ out" #fnsuffix      \
47         : "=&r" (temp)                                        \
48         : "r" (val), "r" (port), "Ir" (PCIO_BASE_##fnsuffix)  \
49         : "cc");                                              \
50 }
51
52
53 #define DECLARE_DYN_IN(sz,fnsuffix,instr)                               \
54 static inline unsigned sz __in##fnsuffix (unsigned int port)            \
55 {                                                                       \
56         unsigned long temp, value;                                      \
57         __asm__ __volatile__(                                           \
58         "cmp    %2, #(1<<28)\n\t"                                       \
59         "mov    %0, %2\n\t"                                             \
60         "addcc  %0, %0, %3\n\t"                                         \
61         "ldr" instr "   %1, [%0, #0 ]   @ in" #fnsuffix         \
62         : "=&r" (temp), "=r" (value)                                    \
63         : "r" (port), "Ir" (PCIO_BASE_##fnsuffix)       \
64         : "cc");                                                        \
65         return (unsigned sz)value;                                      \
66 }
67
68 static inline unsigned int __ioaddr (unsigned int port)
69 {
70         if (__PORT_PCIO(port))
71                 return (unsigned int)(PCIO_BASE + (port));
72         else
73                 return (unsigned int)(0 + (port));
74 }
75
76 #define DECLARE_IO(sz,fnsuffix,instr)   \
77         DECLARE_DYN_IN(sz,fnsuffix,instr) \
78         DECLARE_DYN_OUT(sz,fnsuffix,instr)
79
80 DECLARE_IO(char,b,"b")
81 DECLARE_IO(short,w,"h")
82 DECLARE_IO(int,l,"")
83
84 #undef DECLARE_IO
85 #undef DECLARE_DYN_IN
86
87 /*
88  * Constant address IO functions
89  *
90  * These have to be macros for the 'J' constraint to work -
91  * +/-4096 immediate operand.
92  */
93 #define __outbc(value,port)                                             \
94 ({                                                                      \
95         if (__PORT_PCIO((port)))                                        \
96                 __asm__ __volatile__(                                   \
97                 "strb   %0, [%1, %2]    @ outbc"                        \
98                 : : "r" (value), "r" (PCIO_BASE), "Jr" ((port)));       \
99         else                                                            \
100                 __asm__ __volatile__(                                   \
101                 "strb   %0, [%1, #0]    @ outbc"                        \
102                 : : "r" (value), "r" ((port)));         \
103 })
104
105 #define __inbc(port)                                                    \
106 ({                                                                      \
107         unsigned char result;                                           \
108         if (__PORT_PCIO((port)))                                        \
109                 __asm__ __volatile__(                                   \
110                 "ldrb   %0, [%1, %2]    @ inbc"                         \
111                 : "=r" (result) : "r" (PCIO_BASE), "Jr" ((port)));      \
112         else                                                            \
113                 __asm__ __volatile__(                                   \
114                 "ldrb   %0, [%1, #0]    @ inbc"                         \
115                 : "=r" (result) : "r" ((port)));        \
116         result;                                                         \
117 })
118
119 #define __outwc(value,port)                                             \
120 ({                                                                      \
121         unsigned long v = value;                                        \
122         if (__PORT_PCIO((port)))                                        \
123                 __asm__ __volatile__(                                   \
124                 "strh   %0, [%1, %2]    @ outwc"                        \
125                 : : "r" (v), "r" (PCIO_BASE), "Jr" ((port)));   \
126         else                                                            \
127                 __asm__ __volatile__(                                   \
128                 "strh   %0, [%1, #0]    @ outwc"                        \
129                 : : "r" (v), "r" ((port)));     \
130 })
131
132 #define __inwc(port)                                                    \
133 ({                                                                      \
134         unsigned short result;                                          \
135         if (__PORT_PCIO((port)))                                        \
136                 __asm__ __volatile__(                                   \
137                 "ldrh   %0, [%1, %2]    @ inwc"                         \
138                 : "=r" (result) : "r" (PCIO_BASE), "Jr" ((port)));      \
139         else                                                            \
140                 __asm__ __volatile__(                                   \
141                 "ldrh   %0, [%1, #0]    @ inwc"                         \
142                 : "=r" (result) : "r" ((port)));                \
143         result;                                         \
144 })
145
146 #define __outlc(value,port)                                             \
147 ({                                                                      \
148         unsigned long v = value;                                        \
149         if (__PORT_PCIO((port)))                                        \
150                 __asm__ __volatile__(                                   \
151                 "str    %0, [%1, %2]    @ outlc"                        \
152                 : : "r" (v), "r" (PCIO_BASE), "Jr" ((port)));   \
153         else                                                            \
154                 __asm__ __volatile__(                                   \
155                 "str    %0, [%1, #0]    @ outlc"                        \
156                 : : "r" (v), "r" ((port)));             \
157 })
158
159 #define __inlc(port)                                                    \
160 ({                                                                      \
161         unsigned long result;                                           \
162         if (__PORT_PCIO((port)))                                        \
163                 __asm__ __volatile__(                                   \
164                 "ldr    %0, [%1, %2]    @ inlc"                         \
165                 : "=r" (result) : "r" (PCIO_BASE), "Jr" ((port)));      \
166         else                                                            \
167                 __asm__ __volatile__(                                   \
168                 "ldr    %0, [%1, #0]    @ inlc"                         \
169                 : "=r" (result) : "r" ((port)));                \
170         result;                                                         \
171 })
172
173 #define __ioaddrc(port) (__PORT_PCIO((port)) ? PCIO_BASE + ((port)) : ((port)))
174
175 #define inb(p)          (__builtin_constant_p((p)) ? __inbc(p)     : __inb(p))
176 #define inw(p)          (__builtin_constant_p((p)) ? __inwc(p)     : __inw(p))
177 #define inl(p)          (__builtin_constant_p((p)) ? __inlc(p)     : __inl(p))
178 #define outb(v,p)       (__builtin_constant_p((p)) ? __outbc(v,p) : __outb(v,p))
179 #define outw(v,p)       (__builtin_constant_p((p)) ? __outwc(v,p) : __outw(v,p))
180 #define outl(v,p)       (__builtin_constant_p((p)) ? __outlc(v,p) : __outl(v,p))
181 #define __ioaddr(p)     (__builtin_constant_p((p)) ? __ioaddr(p)  : __ioaddrc(p))
182 /* the following macro is deprecated */
183 #define ioaddr(port)                    __ioaddr((port))
184
185 #define insb(p,d,l)     __raw_readsb(__ioaddr(p),d,l)
186 #define insw(p,d,l)     __raw_readsw(__ioaddr(p),d,l)
187 #define insl(p,d,l)     __raw_readsl(__ioaddr(p),d,l)
188
189 #define outsb(p,d,l)    __raw_writesb(__ioaddr(p),d,l)
190 #define outsw(p,d,l)    __raw_writesw(__ioaddr(p),d,l)
191 #define outsl(p,d,l)    __raw_writesl(__ioaddr(p),d,l)
192
193 /*
194  * 1:1 mapping for ioremapped regions.
195  */
196 #define __mem_pci(x)    (x)
197
198 #endif