This commit was manufactured by cvs2svn to create branch 'vserver'.
[linux-2.6.git] / arch / m32r / kernel / io_oaks32r.c
1 /*
2  *  linux/arch/m32r/kernel/io_oaks32r.c
3  *
4  *  Typical I/O routines for OAKS32R board.
5  *
6  *  Copyright (c) 2001-2004  Hiroyuki Kondo, Hirokazu Takata,
7  *                            Hitoshi Yamamoto, Mamoru Sakugawa
8  */
9
10 /* $Id$ */
11
12 #include <linux/config.h>
13 #include <asm/m32r.h>
14 #include <asm/page.h>
15 #include <asm/io.h>
16
17 #define PORT2ADDR(port)  _port2addr(port)
18
19 static __inline__ void *_port2addr(unsigned long port)
20 {
21         return (void *)(port + NONCACHE_OFFSET);
22 }
23
24 static __inline__  void *_port2addr_ne(unsigned long port)
25 {
26         return (void *)((port<<1) + NONCACHE_OFFSET + 0x02000000);
27 }
28
29 static __inline__ void delay(void)
30 {
31         __asm__ __volatile__ ("push r0; \n\t pop r0;" : : :"memory");
32 }
33
34 /*
35  * NIC I/O function
36  */
37
38 #define PORT2ADDR_NE(port)  _port2addr_ne(port)
39
40 static __inline__ unsigned char _ne_inb(void *portp)
41 {
42         return *(volatile unsigned char *)(portp+1);
43 }
44
45 static __inline__ unsigned short _ne_inw(void *portp)
46 {
47         unsigned short tmp;
48
49         tmp = *(unsigned short *)(portp) & 0xff;
50         tmp |= *(unsigned short *)(portp+2) << 8;
51         return tmp;
52 }
53
54 static __inline__  void _ne_insb(void *portp, void * addr, unsigned long count)
55 {
56         unsigned char *buf = addr;
57         while (count--) *buf++ = *(volatile unsigned char *)(portp+1);
58 }
59
60 static __inline__ void _ne_outb(unsigned char b, void *portp)
61 {
62         *(volatile unsigned char *)(portp+1) = b;
63 }
64
65 static __inline__ void _ne_outw(unsigned short w, void *portp)
66 {
67   *(volatile unsigned short *)portp =  (w >> 8);
68   *(volatile unsigned short *)(portp+2) =  (w & 0xff);
69 }
70
71 unsigned char _inb(unsigned long port)
72 {
73         if (port >= 0x300 && port < 0x320)
74                 return _ne_inb(PORT2ADDR_NE(port));
75
76         return *(volatile unsigned char *)PORT2ADDR(port);
77 }
78
79 unsigned short _inw(unsigned long port)
80 {
81         if (port >= 0x300 && port < 0x320)
82                 return _ne_inw(PORT2ADDR_NE(port));
83
84         return *(volatile unsigned short *)PORT2ADDR(port);
85 }
86
87 unsigned long _inl(unsigned long port)
88 {
89         return *(volatile unsigned long *)PORT2ADDR(port);
90 }
91
92 unsigned char _inb_p(unsigned long port)
93 {
94         unsigned char  v;
95
96         if (port >= 0x300 && port < 0x320)
97                 v = _ne_inb(PORT2ADDR_NE(port));
98         else
99                 v = *(volatile unsigned char *)PORT2ADDR(port);
100
101         delay();
102         return (v);
103 }
104
105 unsigned short _inw_p(unsigned long port)
106 {
107         unsigned short  v;
108
109         if (port >= 0x300 && port < 0x320)
110                 v = _ne_inw(PORT2ADDR_NE(port));
111         else
112                 v = *(volatile unsigned short *)PORT2ADDR(port);
113
114         delay();
115         return (v);
116 }
117
118 unsigned long _inl_p(unsigned long port)
119 {
120         unsigned long  v;
121
122         v = *(volatile unsigned long *)PORT2ADDR(port);
123         delay();
124         return (v);
125 }
126
127 void _outb(unsigned char b, unsigned long port)
128 {
129         if (port >= 0x300 && port < 0x320)
130                 _ne_outb(b, PORT2ADDR_NE(port));
131         else
132                 *(volatile unsigned char *)PORT2ADDR(port) = b;
133 }
134
135 void _outw(unsigned short w, unsigned long port)
136 {
137         if (port >= 0x300 && port < 0x320)
138                 _ne_outw(w, PORT2ADDR_NE(port));
139         else
140                 *(volatile unsigned short *)PORT2ADDR(port) = w;
141 }
142
143 void _outl(unsigned long l, unsigned long port)
144 {
145         *(volatile unsigned long *)PORT2ADDR(port) = l;
146 }
147
148 void _outb_p(unsigned char b, unsigned long port)
149 {
150         if (port >= 0x300 && port < 0x320)
151                 _ne_outb(b, PORT2ADDR_NE(port));
152         else
153                 *(volatile unsigned char *)PORT2ADDR(port) = b;
154
155         delay();
156 }
157
158 void _outw_p(unsigned short w, unsigned long port)
159 {
160         if (port >= 0x300 && port < 0x320)
161                 _ne_outw(w, PORT2ADDR_NE(port));
162         else
163                 *(volatile unsigned short *)PORT2ADDR(port) = w;
164
165         delay();
166 }
167
168 void _outl_p(unsigned long l, unsigned long port)
169 {
170         *(volatile unsigned long *)PORT2ADDR(port) = l;
171         delay();
172 }
173
174 void _insb(unsigned int port, void * addr, unsigned long count)
175 {
176         if (port >= 0x300 && port < 0x320)
177                 _ne_insb(PORT2ADDR_NE(port), addr, count);
178         else {
179                 unsigned char *buf = addr;
180                 unsigned char *portp = PORT2ADDR(port);
181                 while(count--) *buf++ = *(volatile unsigned char *)portp;
182         }
183 }
184
185 void _insw(unsigned int port, void * addr, unsigned long count)
186 {
187         unsigned short *buf = addr;
188         unsigned short *portp;
189
190         if (port >= 0x300 && port < 0x320) {
191                 portp = PORT2ADDR_NE(port);
192                 while (count--) *buf++ = _ne_inw(portp);
193         } else {
194                 portp = PORT2ADDR(port);
195                 while (count--) *buf++ = *(volatile unsigned short *)portp;
196         }
197 }
198
199 void _insl(unsigned int port, void * addr, unsigned long count)
200 {
201         unsigned long *buf = addr;
202         unsigned long *portp;
203
204         portp = PORT2ADDR(port);
205         while (count--) *buf++ = *(volatile unsigned long *)portp;
206 }
207
208 void _outsb(unsigned int port, const void * addr, unsigned long count)
209 {
210         const unsigned char *buf = addr;
211         unsigned char *portp;
212
213         if (port >= 0x300 && port < 0x320) {
214                 portp = PORT2ADDR_NE(port);
215                 while (count--) _ne_outb(*buf++, portp);
216         } else {
217                 portp = PORT2ADDR(port);
218                 while(count--) *(volatile unsigned char *)portp = *buf++;
219         }
220 }
221
222 void _outsw(unsigned int port, const void * addr, unsigned long count)
223 {
224         const unsigned short *buf = addr;
225         unsigned short *portp;
226
227         if (port >= 0x300 && port < 0x320) {
228                 portp = PORT2ADDR_NE(port);
229                 while (count--) _ne_outw(*buf++, portp);
230         } else {
231                 portp = PORT2ADDR(port);
232                 while(count--) *(volatile unsigned short *)portp = *buf++;
233         }
234 }
235
236 void _outsl(unsigned int port, const void * addr, unsigned long count)
237 {
238         const unsigned long *buf = addr;
239         unsigned char *portp;
240
241         portp = PORT2ADDR(port);
242         while(count--) *(volatile unsigned long *)portp = *buf++;
243 }