Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
io.c
Go to the documentation of this file.
1 /*
2  * linux/arch/m32r/platforms/mappi/io.c
3  *
4  * Typical I/O routines for Mappi board.
5  *
6  * Copyright (c) 2001-2005 Hiroyuki Kondo, Hirokazu Takata,
7  * Hitoshi Yamamoto
8  */
9 
10 #include <asm/m32r.h>
11 #include <asm/page.h>
12 #include <asm/io.h>
13 #include <asm/byteorder.h>
14 
15 #if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC)
16 #include <linux/types.h>
17 
18 #define M32R_PCC_IOMAP_SIZE 0x1000
19 
20 #define M32R_PCC_IOSTART0 0x1000
21 #define M32R_PCC_IOEND0 (M32R_PCC_IOSTART0 + M32R_PCC_IOMAP_SIZE - 1)
22 #define M32R_PCC_IOSTART1 0x2000
23 #define M32R_PCC_IOEND1 (M32R_PCC_IOSTART1 + M32R_PCC_IOMAP_SIZE - 1)
24 
25 extern void pcc_ioread(int, unsigned long, void *, size_t, size_t, int);
26 extern void pcc_iowrite(int, unsigned long, void *, size_t, size_t, int);
27 #endif /* CONFIG_PCMCIA && CONFIG_M32R_PCC */
28 
29 #define PORT2ADDR(port) _port2addr(port)
30 
31 static inline void *_port2addr(unsigned long port)
32 {
33  return (void *)(port | NONCACHE_OFFSET);
34 }
35 
36 static inline void *_port2addr_ne(unsigned long port)
37 {
38  return (void *)((port<<1) + NONCACHE_OFFSET + 0x0C000000);
39 }
40 
41 static inline void delay(void)
42 {
43  __asm__ __volatile__ ("push r0; \n\t pop r0;" : : :"memory");
44 }
45 
46 /*
47  * NIC I/O function
48  */
49 
50 #define PORT2ADDR_NE(port) _port2addr_ne(port)
51 
52 static inline unsigned char _ne_inb(void *portp)
53 {
54  return (unsigned char) *(volatile unsigned short *)portp;
55 }
56 
57 static inline unsigned short _ne_inw(void *portp)
58 {
59  unsigned short tmp;
60 
61  tmp = *(volatile unsigned short *)portp;
62  return le16_to_cpu(tmp);
63 }
64 
65 static inline void _ne_outb(unsigned char b, void *portp)
66 {
67  *(volatile unsigned short *)portp = (unsigned short)b;
68 }
69 
70 static inline void _ne_outw(unsigned short w, void *portp)
71 {
72  *(volatile unsigned short *)portp = cpu_to_le16(w);
73 }
74 
75 unsigned char _inb(unsigned long port)
76 {
77  if (port >= 0x300 && port < 0x320)
78  return _ne_inb(PORT2ADDR_NE(port));
79  else
80 #if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC)
81  if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
82  unsigned char b;
83  pcc_ioread(0, port, &b, sizeof(b), 1, 0);
84  return b;
85  } else if (port >= M32R_PCC_IOSTART1 && port <= M32R_PCC_IOEND1) {
86  unsigned char b;
87  pcc_ioread(1, port, &b, sizeof(b), 1, 0);
88  return b;
89  } else
90 #endif
91 
92  return *(volatile unsigned char *)PORT2ADDR(port);
93 }
94 
95 unsigned short _inw(unsigned long port)
96 {
97  if (port >= 0x300 && port < 0x320)
98  return _ne_inw(PORT2ADDR_NE(port));
99  else
100 #if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC)
101  if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
102  unsigned short w;
103  pcc_ioread(0, port, &w, sizeof(w), 1, 0);
104  return w;
105  } else if (port >= M32R_PCC_IOSTART1 && port <= M32R_PCC_IOEND1) {
106  unsigned short w;
107  pcc_ioread(1, port, &w, sizeof(w), 1, 0);
108  return w;
109  } else
110 #endif
111  return *(volatile unsigned short *)PORT2ADDR(port);
112 }
113 
114 unsigned long _inl(unsigned long port)
115 {
116 #if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC)
117  if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
118  unsigned long l;
119  pcc_ioread(0, port, &l, sizeof(l), 1, 0);
120  return l;
121  } else if (port >= M32R_PCC_IOSTART1 && port <= M32R_PCC_IOEND1) {
122  unsigned short l;
123  pcc_ioread(1, port, &l, sizeof(l), 1, 0);
124  return l;
125  } else
126 #endif
127  return *(volatile unsigned long *)PORT2ADDR(port);
128 }
129 
130 unsigned char _inb_p(unsigned long port)
131 {
132  unsigned char v = _inb(port);
133  delay();
134  return (v);
135 }
136 
137 unsigned short _inw_p(unsigned long port)
138 {
139  unsigned short v = _inw(port);
140  delay();
141  return (v);
142 }
143 
144 unsigned long _inl_p(unsigned long port)
145 {
146  unsigned long v = _inl(port);
147  delay();
148  return (v);
149 }
150 
151 void _outb(unsigned char b, unsigned long port)
152 {
153  if (port >= 0x300 && port < 0x320)
154  _ne_outb(b, PORT2ADDR_NE(port));
155  else
156 #if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC)
157  if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
158  pcc_iowrite(0, port, &b, sizeof(b), 1, 0);
159  } else if (port >= M32R_PCC_IOSTART1 && port <= M32R_PCC_IOEND1) {
160  pcc_iowrite(1, port, &b, sizeof(b), 1, 0);
161  } else
162 #endif
163  *(volatile unsigned char *)PORT2ADDR(port) = b;
164 }
165 
166 void _outw(unsigned short w, unsigned long port)
167 {
168  if (port >= 0x300 && port < 0x320)
169  _ne_outw(w, PORT2ADDR_NE(port));
170  else
171 #if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC)
172  if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
173  pcc_iowrite(0, port, &w, sizeof(w), 1, 0);
174  } else if (port >= M32R_PCC_IOSTART1 && port <= M32R_PCC_IOEND1) {
175  pcc_iowrite(1, port, &w, sizeof(w), 1, 0);
176  } else
177 #endif
178  *(volatile unsigned short *)PORT2ADDR(port) = w;
179 }
180 
181 void _outl(unsigned long l, unsigned long port)
182 {
183 #if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC)
184  if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
185  pcc_iowrite(0, port, &l, sizeof(l), 1, 0);
186  } else if (port >= M32R_PCC_IOSTART1 && port <= M32R_PCC_IOEND1) {
187  pcc_iowrite(1, port, &l, sizeof(l), 1, 0);
188  } else
189 #endif
190  *(volatile unsigned long *)PORT2ADDR(port) = l;
191 }
192 
193 void _outb_p(unsigned char b, unsigned long port)
194 {
195  _outb(b, port);
196  delay();
197 }
198 
199 void _outw_p(unsigned short w, unsigned long port)
200 {
201  _outw(w, port);
202  delay();
203 }
204 
205 void _outl_p(unsigned long l, unsigned long port)
206 {
207  _outl(l, port);
208  delay();
209 }
210 
211 void _insb(unsigned int port, void *addr, unsigned long count)
212 {
213  unsigned short *buf = addr;
214  unsigned short *portp;
215 
216  if (port >= 0x300 && port < 0x320){
217  portp = PORT2ADDR_NE(port);
218  while (count--)
219  *buf++ = *(volatile unsigned char *)portp;
220 #if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC)
221  } else if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
222  pcc_ioread(0, port, (void *)addr, sizeof(unsigned char),
223  count, 1);
224  } else if (port >= M32R_PCC_IOSTART1 && port <= M32R_PCC_IOEND1) {
225  pcc_ioread(1, port, (void *)addr, sizeof(unsigned char),
226  count, 1);
227 #endif
228  } else {
229  portp = PORT2ADDR(port);
230  while (count--)
231  *buf++ = *(volatile unsigned char *)portp;
232  }
233 }
234 
235 void _insw(unsigned int port, void *addr, unsigned long count)
236 {
237  unsigned short *buf = addr;
238  unsigned short *portp;
239 
240  if (port >= 0x300 && port < 0x320) {
241  portp = PORT2ADDR_NE(port);
242  while (count--)
243  *buf++ = _ne_inw(portp);
244 #if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC)
245  } else if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
246  pcc_ioread(0, port, (void *)addr, sizeof(unsigned short),
247  count, 1);
248  } else if (port >= M32R_PCC_IOSTART1 && port <= M32R_PCC_IOEND1) {
249  pcc_ioread(1, port, (void *)addr, sizeof(unsigned short),
250  count, 1);
251 #endif
252  } else {
253  portp = PORT2ADDR(port);
254  while (count--)
255  *buf++ = *(volatile unsigned short *)portp;
256  }
257 }
258 
259 void _insl(unsigned int port, void *addr, unsigned long count)
260 {
261  unsigned long *buf = addr;
262  unsigned long *portp;
263 
264  portp = PORT2ADDR(port);
265  while (count--)
266  *buf++ = *(volatile unsigned long *)portp;
267 }
268 
269 void _outsb(unsigned int port, const void *addr, unsigned long count)
270 {
271  const unsigned char *buf = addr;
272  unsigned char *portp;
273 
274  if (port >= 0x300 && port < 0x320) {
275  portp = PORT2ADDR_NE(port);
276  while (count--)
277  _ne_outb(*buf++, portp);
278 #if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC)
279  } else if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
280  pcc_iowrite(0, port, (void *)addr, sizeof(unsigned char),
281  count, 1);
282  } else if (port >= M32R_PCC_IOSTART1 && port <= M32R_PCC_IOEND1) {
283  pcc_iowrite(1, port, (void *)addr, sizeof(unsigned char),
284  count, 1);
285 #endif
286  } else {
287  portp = PORT2ADDR(port);
288  while (count--)
289  *(volatile unsigned char *)portp = *buf++;
290  }
291 }
292 
293 void _outsw(unsigned int port, const void *addr, unsigned long count)
294 {
295  const unsigned short *buf = addr;
296  unsigned short *portp;
297 
298  if (port >= 0x300 && port < 0x320) {
299  portp = PORT2ADDR_NE(port);
300  while (count--)
301  _ne_outw(*buf++, portp);
302 #if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC)
303  } else if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
304  pcc_iowrite(0, port, (void *)addr, sizeof(unsigned short),
305  count, 1);
306  } else if (port >= M32R_PCC_IOSTART1 && port <= M32R_PCC_IOEND1) {
307  pcc_iowrite(1, port, (void *)addr, sizeof(unsigned short),
308  count, 1);
309 #endif
310  } else {
311  portp = PORT2ADDR(port);
312  while (count--)
313  *(volatile unsigned short *)portp = *buf++;
314  }
315 }
316 
317 void _outsl(unsigned int port, const void *addr, unsigned long count)
318 {
319  const unsigned long *buf = addr;
320  unsigned char *portp;
321 
322  portp = PORT2ADDR(port);
323  while (count--)
324  *(volatile unsigned long *)portp = *buf++;
325 }