vserver 1.9.5.x5
[linux-2.6.git] / arch / arm / mach-ebsa110 / io.c
1 /*
2  *  linux/arch/arm/mach-ebsa110/isamem.c
3  *
4  *  Copyright (C) 2001 Russell King
5  *
6  * Perform "ISA" memory and IO accesses.  The EBSA110 has some "peculiarities"
7  * in the way it handles accesses to odd IO ports on 16-bit devices.  These
8  * devices have their D0-D15 lines connected to the processors D0-D15 lines.
9  * Since they expect all byte IO operations to be performed on D0-D7, and the
10  * StrongARM expects to transfer the byte to these odd addresses on D8-D15,
11  * we must use a trick to get the required behaviour.
12  *
13  * The trick employed here is to use long word stores to odd address -1.  The
14  * glue logic picks this up as a "trick" access, and asserts the LSB of the
15  * peripherals address bus, thereby accessing the odd IO port.  Meanwhile, the
16  * StrongARM transfers its data on D0-D7 as expected.
17  *
18  * Things get more interesting on the pass-1 EBSA110 - the PCMCIA controller
19  * wiring was screwed in such a way that it had limited memory space access.
20  * Luckily, the work-around for this is not too horrible.  See
21  * __isamem_convert_addr for the details.
22  */
23 #include <linux/module.h>
24 #include <linux/kernel.h>
25 #include <linux/types.h>
26
27 #include <asm/io.h>
28 #include <asm/page.h>
29
30 static void __iomem *__isamem_convert_addr(void __iomem *addr)
31 {
32         u32 ret, a = (u32 __force) addr;
33
34         /*
35          * The PCMCIA controller is wired up as follows:
36          *        +---------+---------+---------+---------+---------+---------+
37          * PCMCIA | 2 2 2 2 | 1 1 1 1 | 1 1 1 1 | 1 1     |         |         |
38          *        | 3 2 1 0 | 9 8 7 6 | 5 4 3 2 | 1 0 9 8 | 7 6 5 4 | 3 2 1 0 |
39          *        +---------+---------+---------+---------+---------+---------+
40          *  CPU   | 2 2 2 2 | 2 1 1 1 | 1 1 1 1 | 1 1 1   |         |         |
41          *        | 4 3 2 1 | 0 9 9 8 | 7 6 5 4 | 3 2 0 9 | 8 7 6 5 | 4 3 2 x |
42          *        +---------+---------+---------+---------+---------+---------+
43          *
44          * This means that we can access PCMCIA regions as follows:
45          *      0x*10000 -> 0x*1ffff
46          *      0x*70000 -> 0x*7ffff
47          *      0x*90000 -> 0x*9ffff
48          *      0x*f0000 -> 0x*fffff
49          */
50         ret  = (a & 0xf803fe) << 1;
51         ret |= (a & 0x03fc00) << 2;
52
53         ret += 0xe8000000;
54
55         if ((a & 0x20000) == (a & 0x40000) >> 1)
56                 return (void __iomem *)ret;
57
58         BUG();
59         return NULL;
60 }
61
62 /*
63  * read[bwl] and write[bwl]
64  */
65 u8 __readb(void __iomem *addr)
66 {
67         void __iomem *a = __isamem_convert_addr(addr);
68         u32 ret;
69
70         if ((unsigned long)addr & 1)
71                 ret = __raw_readl(a);
72         else
73                 ret = __raw_readb(a);
74         return ret;
75 }
76
77 u16 __readw(void __iomem *addr)
78 {
79         void __iomem *a = __isamem_convert_addr(addr);
80
81         if ((unsigned long)addr & 1)
82                 BUG();
83
84         return __raw_readw(a);
85 }
86
87 u32 __readl(void __iomem *addr)
88 {
89         void __iomem *a = __isamem_convert_addr(addr);
90         u32 ret;
91
92         if ((unsigned long)addr & 3)
93                 BUG();
94
95         ret = __raw_readw(a);
96         ret |= __raw_readw(a + 4) << 16;
97         return ret;
98 }
99
100 EXPORT_SYMBOL(__readb);
101 EXPORT_SYMBOL(__readw);
102 EXPORT_SYMBOL(__readl);
103
104 void __writeb(u8 val, void __iomem *addr)
105 {
106         void __iomem *a = __isamem_convert_addr(addr);
107
108         if ((unsigned long)addr & 1)
109                 __raw_writel(val, a);
110         else
111                 __raw_writeb(val, a);
112 }
113
114 void __writew(u16 val, void __iomem *addr)
115 {
116         void __iomem *a = __isamem_convert_addr(addr);
117
118         if ((unsigned long)addr & 1)
119                 BUG();
120
121         __raw_writew(val, a);
122 }
123
124 void __writel(u32 val, void __iomem *addr)
125 {
126         void __iomem *a = __isamem_convert_addr(addr);
127
128         if ((unsigned long)addr & 3)
129                 BUG();
130
131         __raw_writew(val, a);
132         __raw_writew(val >> 16, a + 4);
133 }
134
135 EXPORT_SYMBOL(__writeb);
136 EXPORT_SYMBOL(__writew);
137 EXPORT_SYMBOL(__writel);
138
139 #define SUPERIO_PORT(p) \
140         (((p) >> 3) == (0x3f8 >> 3) || \
141          ((p) >> 3) == (0x2f8 >> 3) || \
142          ((p) >> 3) == (0x378 >> 3))
143
144 /*
145  * We're addressing an 8 or 16-bit peripheral which tranfers
146  * odd addresses on the low ISA byte lane.
147  */
148 u8 __inb8(unsigned int port)
149 {
150         u32 ret;
151
152         /*
153          * The SuperIO registers use sane addressing techniques...
154          */
155         if (SUPERIO_PORT(port))
156                 ret = __raw_readb(ISAIO_BASE + (port << 2));
157         else {
158                 void __iomem *a = ISAIO_BASE + ((port & ~1) << 1);
159
160                 /*
161                  * Shame nothing else does
162                  */
163                 if (port & 1)
164                         ret = __raw_readl(a);
165                 else
166                         ret = __raw_readb(a);
167         }
168         return ret;
169 }
170
171 /*
172  * We're addressing a 16-bit peripheral which transfers odd
173  * addresses on the high ISA byte lane.
174  */
175 u8 __inb16(unsigned int port)
176 {
177         u32 ret;
178
179         /*
180          * The SuperIO registers use sane addressing techniques...
181          */
182         if (SUPERIO_PORT(port))
183                 ret = __raw_readb(ISAIO_BASE + (port << 2));
184         else {
185                 void __iomem *a = ISAIO_BASE + ((port & ~1) << 1);
186
187                 /*
188                  * Shame nothing else does
189                  */
190                 ret = __raw_readb(a + (port & 1));
191         }
192         return ret;
193 }
194
195 u16 __inw(unsigned int port)
196 {
197         u32 ret;
198
199         /*
200          * The SuperIO registers use sane addressing techniques...
201          */
202         if (SUPERIO_PORT(port))
203                 ret = __raw_readw(ISAIO_BASE + (port << 2));
204         else {
205                 void __iomem *a = ISAIO_BASE + ((port & ~1) << 1);
206
207                 /*
208                  * Shame nothing else does
209                  */
210                 if (port & 1)
211                         BUG();
212
213                 ret = __raw_readw(a);
214         }
215         return ret;
216 }
217
218 /*
219  * Fake a 32-bit read with two 16-bit reads.  Needed for 3c589.
220  */
221 u32 __inl(unsigned int port)
222 {
223         void __iomem *a;
224
225         if (SUPERIO_PORT(port) || port & 3)
226                 BUG();
227
228         a = ISAIO_BASE + (port << 1);
229
230         return __raw_readw(a) | __raw_readw(a + 4) << 16;
231 }
232
233 EXPORT_SYMBOL(__inb8);
234 EXPORT_SYMBOL(__inb16);
235 EXPORT_SYMBOL(__inw);
236 EXPORT_SYMBOL(__inl);
237
238 void __outb8(u8 val, unsigned int port)
239 {
240         /*
241          * The SuperIO registers use sane addressing techniques...
242          */
243         if (SUPERIO_PORT(port))
244                 __raw_writeb(val, ISAIO_BASE + (port << 2));
245         else {
246                 void __iomem *a = ISAIO_BASE + ((port & ~1) << 1);
247
248                 /*
249                  * Shame nothing else does
250                  */
251                 if (port & 1)
252                         __raw_writel(val, a);
253                 else
254                         __raw_writeb(val, a);
255         }
256 }
257
258 void __outb16(u8 val, unsigned int port)
259 {
260         /*
261          * The SuperIO registers use sane addressing techniques...
262          */
263         if (SUPERIO_PORT(port))
264                 __raw_writeb(val, ISAIO_BASE + (port << 2));
265         else {
266                 void __iomem *a = ISAIO_BASE + ((port & ~1) << 1);
267
268                 /*
269                  * Shame nothing else does
270                  */
271                 __raw_writeb(val, a + (port & 1));
272         }
273 }
274
275 void __outw(u16 val, unsigned int port)
276 {
277         u32 off;
278
279         /*
280          * The SuperIO registers use sane addressing techniques...
281          */
282         if (SUPERIO_PORT(port))
283                 off = port << 2;
284         else {
285                 off = port << 1;
286                 if (port & 1)
287                         BUG();
288
289         }
290         __raw_writew(val, ISAIO_BASE + off);
291 }
292
293 void __outl(u32 val, unsigned int port)
294 {
295         BUG();
296 }
297
298 EXPORT_SYMBOL(__outb8);
299 EXPORT_SYMBOL(__outb16);
300 EXPORT_SYMBOL(__outw);
301 EXPORT_SYMBOL(__outl);
302
303 extern void __arch_writesb(unsigned long virt, const void *from, int len);
304 extern void __arch_writesw(unsigned long virt, const void *from, int len);
305 extern void __arch_writesl(unsigned long virt, const void *from, int len);
306 extern void __arch_readsb(unsigned long virt, void *from, int len);
307 extern void __arch_readsw(unsigned long virt, void *from, int len);
308 extern void __arch_readsl(unsigned long virt, void *from, int len);
309
310 void outsb(unsigned int port, const void *from, int len)
311 {
312         u32 off;
313
314         if (SUPERIO_PORT(port))
315                 off = port << 2;
316         else {
317                 off = (port & ~1) << 1;
318                 if (port & 1)
319                         BUG();
320         }
321
322         __raw_writesb(ISAIO_BASE + off, from, len);
323 }
324
325 void insb(unsigned int port, void *from, int len)
326 {
327         u32 off;
328
329         if (SUPERIO_PORT(port))
330                 off = port << 2;
331         else {
332                 off = (port & ~1) << 1;
333                 if (port & 1)
334                         BUG();
335         }
336
337         __raw_readsb(ISAIO_BASE + off, from, len);
338 }
339
340 EXPORT_SYMBOL(outsb);
341 EXPORT_SYMBOL(insb);
342
343 void outsw(unsigned int port, const void *from, int len)
344 {
345         u32 off;
346
347         if (SUPERIO_PORT(port))
348                 off = port << 2;
349         else {
350                 off = (port & ~1) << 1;
351                 if (port & 1)
352                         BUG();
353         }
354
355         __raw_writesw(ISAIO_BASE + off, from, len);
356 }
357
358 void insw(unsigned int port, void *from, int len)
359 {
360         u32 off;
361
362         if (SUPERIO_PORT(port))
363                 off = port << 2;
364         else {
365                 off = (port & ~1) << 1;
366                 if (port & 1)
367                         BUG();
368         }
369
370         __raw_readsw(ISAIO_BASE + off, from, len);
371 }
372
373 EXPORT_SYMBOL(outsw);
374 EXPORT_SYMBOL(insw);
375
376 /*
377  * We implement these as 16-bit insw/outsw, mainly for
378  * 3c589 cards.
379  */
380 void outsl(unsigned int port, const void *from, int len)
381 {
382         u32 off = port << 1;
383
384         if (SUPERIO_PORT(port) || port & 3)
385                 BUG();
386
387         __raw_writesw(ISAIO_BASE + off, from, len << 1);
388 }
389
390 void insl(unsigned int port, void *from, int len)
391 {
392         u32 off = port << 1;
393
394         if (SUPERIO_PORT(port) || port & 3)
395                 BUG();
396
397         __raw_readsw(ISAIO_BASE + off, from, len << 1);
398 }
399
400 EXPORT_SYMBOL(outsl);
401 EXPORT_SYMBOL(insl);