VServer 1.9.2 (patch-2.6.8.1-vs1.9.2.diff)
[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 u32 __isamem_convert_addr(void *addr)
31 {
32         u32 ret, a = (u32) 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 ret;
57
58         BUG();
59         return 0;
60 }
61
62 /*
63  * read[bwl] and write[bwl]
64  */
65 u8 __readb(void *addr)
66 {
67         u32 ret, a = __isamem_convert_addr(addr);
68
69         if ((int)addr & 1)
70                 ret = __raw_readl(a);
71         else
72                 ret = __raw_readb(a);
73         return ret;
74 }
75
76 u16 __readw(void *addr)
77 {
78         u32 a = __isamem_convert_addr(addr);
79
80         if ((int)addr & 1)
81                 BUG();
82
83         return __raw_readw(a);
84 }
85
86 u32 __readl(void *addr)
87 {
88         u32 ret, a = __isamem_convert_addr(addr);
89
90         if ((int)addr & 3)
91                 BUG();
92
93         ret = __raw_readw(a);
94         ret |= __raw_readw(a + 4) << 16;
95         return ret;
96 }
97
98 EXPORT_SYMBOL(__readb);
99 EXPORT_SYMBOL(__readw);
100 EXPORT_SYMBOL(__readl);
101
102 void __writeb(u8 val, void *addr)
103 {
104         u32 a = __isamem_convert_addr(addr);
105
106         if ((int)addr & 1)
107                 __raw_writel(val, a);
108         else
109                 __raw_writeb(val, a);
110 }
111
112 void __writew(u16 val, void *addr)
113 {
114         u32 a = __isamem_convert_addr(addr);
115
116         if ((int)addr & 1)
117                 BUG();
118
119         __raw_writew(val, a);
120 }
121
122 void __writel(u32 val, void *addr)
123 {
124         u32 a = __isamem_convert_addr(addr);
125
126         if ((int)addr & 3)
127                 BUG();
128
129         __raw_writew(val, a);
130         __raw_writew(val >> 16, a + 4);
131 }
132
133 EXPORT_SYMBOL(__writeb);
134 EXPORT_SYMBOL(__writew);
135 EXPORT_SYMBOL(__writel);
136
137 #define SUPERIO_PORT(p) \
138         (((p) >> 3) == (0x3f8 >> 3) || \
139          ((p) >> 3) == (0x2f8 >> 3) || \
140          ((p) >> 3) == (0x378 >> 3))
141
142 /*
143  * We're addressing an 8 or 16-bit peripheral which tranfers
144  * odd addresses on the low ISA byte lane.
145  */
146 u8 __inb8(unsigned int port)
147 {
148         u32 ret;
149
150         /*
151          * The SuperIO registers use sane addressing techniques...
152          */
153         if (SUPERIO_PORT(port))
154                 ret = __raw_readb(ISAIO_BASE + (port << 2));
155         else {
156                 u32 a = ISAIO_BASE + ((port & ~1) << 1);
157
158                 /*
159                  * Shame nothing else does
160                  */
161                 if (port & 1)
162                         ret = __raw_readl(a);
163                 else
164                         ret = __raw_readb(a);
165         }
166         return ret;
167 }
168
169 /*
170  * We're addressing a 16-bit peripheral which transfers odd
171  * addresses on the high ISA byte lane.
172  */
173 u8 __inb16(unsigned int port)
174 {
175         u32 ret;
176
177         /*
178          * The SuperIO registers use sane addressing techniques...
179          */
180         if (SUPERIO_PORT(port))
181                 ret = __raw_readb(ISAIO_BASE + (port << 2));
182         else {
183                 u32 a = ISAIO_BASE + ((port & ~1) << 1);
184
185                 /*
186                  * Shame nothing else does
187                  */
188                 ret = __raw_readb(a + (port & 1));
189         }
190         return ret;
191 }
192
193 u16 __inw(unsigned int port)
194 {
195         u32 ret;
196
197         /*
198          * The SuperIO registers use sane addressing techniques...
199          */
200         if (SUPERIO_PORT(port))
201                 ret = __raw_readw(ISAIO_BASE + (port << 2));
202         else {
203                 u32 a = ISAIO_BASE + ((port & ~1) << 1);
204
205                 /*
206                  * Shame nothing else does
207                  */
208                 if (port & 1)
209                         BUG();
210
211                 ret = __raw_readw(a);
212         }
213         return ret;
214 }
215
216 /*
217  * Fake a 32-bit read with two 16-bit reads.  Needed for 3c589.
218  */
219 u32 __inl(unsigned int port)
220 {
221         u32 a;
222
223         if (SUPERIO_PORT(port) || port & 3)
224                 BUG();
225
226         a = ISAIO_BASE + (port << 1);
227
228         return __raw_readw(a) | __raw_readw(a + 4) << 16;
229 }
230
231 EXPORT_SYMBOL(__inb8);
232 EXPORT_SYMBOL(__inb16);
233 EXPORT_SYMBOL(__inw);
234 EXPORT_SYMBOL(__inl);
235
236 void __outb8(u8 val, unsigned int port)
237 {
238         /*
239          * The SuperIO registers use sane addressing techniques...
240          */
241         if (SUPERIO_PORT(port))
242                 __raw_writeb(val, ISAIO_BASE + (port << 2));
243         else {
244                 u32 a = ISAIO_BASE + ((port & ~1) << 1);
245
246                 /*
247                  * Shame nothing else does
248                  */
249                 if (port & 1)
250                         __raw_writel(val, a);
251                 else
252                         __raw_writeb(val, a);
253         }
254 }
255
256 void __outb16(u8 val, unsigned int port)
257 {
258         /*
259          * The SuperIO registers use sane addressing techniques...
260          */
261         if (SUPERIO_PORT(port))
262                 __raw_writeb(val, ISAIO_BASE + (port << 2));
263         else {
264                 u32 a = ISAIO_BASE + ((port & ~1) << 1);
265
266                 /*
267                  * Shame nothing else does
268                  */
269                 __raw_writeb(val, a + (port & 1));
270         }
271 }
272
273 void __outw(u16 val, unsigned int port)
274 {
275         u32 off;
276
277         /*
278          * The SuperIO registers use sane addressing techniques...
279          */
280         if (SUPERIO_PORT(port))
281                 off = port << 2;
282         else {
283                 off = port << 1;
284                 if (port & 1)
285                         BUG();
286
287         }
288         __raw_writew(val, ISAIO_BASE + off);
289 }
290
291 void __outl(u32 val, unsigned int port)
292 {
293         BUG();
294 }
295
296 EXPORT_SYMBOL(__outb8);
297 EXPORT_SYMBOL(__outb16);
298 EXPORT_SYMBOL(__outw);
299 EXPORT_SYMBOL(__outl);
300
301 extern void __arch_writesb(unsigned long virt, const void *from, int len);
302 extern void __arch_writesw(unsigned long virt, const void *from, int len);
303 extern void __arch_writesl(unsigned long virt, const void *from, int len);
304 extern void __arch_readsb(unsigned long virt, void *from, int len);
305 extern void __arch_readsw(unsigned long virt, void *from, int len);
306 extern void __arch_readsl(unsigned long virt, void *from, int len);
307
308 void outsb(unsigned int port, const void *from, int len)
309 {
310         u32 off;
311
312         if (SUPERIO_PORT(port))
313                 off = port << 2;
314         else {
315                 off = (port & ~1) << 1;
316                 if (port & 1)
317                         BUG();
318         }
319
320         __raw_writesb(ISAIO_BASE + off, from, len);
321 }
322
323 void insb(unsigned int port, void *from, int len)
324 {
325         u32 off;
326
327         if (SUPERIO_PORT(port))
328                 off = port << 2;
329         else {
330                 off = (port & ~1) << 1;
331                 if (port & 1)
332                         BUG();
333         }
334
335         __raw_readsb(ISAIO_BASE + off, from, len);
336 }
337
338 EXPORT_SYMBOL(outsb);
339 EXPORT_SYMBOL(insb);
340
341 void outsw(unsigned int port, const void *from, int len)
342 {
343         u32 off;
344
345         if (SUPERIO_PORT(port))
346                 off = port << 2;
347         else {
348                 off = (port & ~1) << 1;
349                 if (port & 1)
350                         BUG();
351         }
352
353         __raw_writesw(ISAIO_BASE + off, from, len);
354 }
355
356 void insw(unsigned int port, void *from, int len)
357 {
358         u32 off;
359
360         if (SUPERIO_PORT(port))
361                 off = port << 2;
362         else {
363                 off = (port & ~1) << 1;
364                 if (port & 1)
365                         BUG();
366         }
367
368         __raw_readsw(ISAIO_BASE + off, from, len);
369 }
370
371 EXPORT_SYMBOL(outsw);
372 EXPORT_SYMBOL(insw);
373
374 /*
375  * We implement these as 16-bit insw/outsw, mainly for
376  * 3c589 cards.
377  */
378 void outsl(unsigned int port, const void *from, int len)
379 {
380         u32 off = port << 1;
381
382         if (SUPERIO_PORT(port) || port & 3)
383                 BUG();
384
385         __raw_writesw(ISAIO_BASE + off, from, len << 1);
386 }
387
388 void insl(unsigned int port, void *from, int len)
389 {
390         u32 off = port << 1;
391
392         if (SUPERIO_PORT(port) || port & 3)
393                 BUG();
394
395         __raw_readsw(ISAIO_BASE + off, from, len << 1);
396 }
397
398 EXPORT_SYMBOL(outsl);
399 EXPORT_SYMBOL(insl);