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