diff options
Diffstat (limited to 'arch/m32r/kernel/io_usrv.c')
-rw-r--r-- | arch/m32r/kernel/io_usrv.c | 249 |
1 files changed, 249 insertions, 0 deletions
diff --git a/arch/m32r/kernel/io_usrv.c b/arch/m32r/kernel/io_usrv.c new file mode 100644 index 000000000000..27928a0b99ed --- /dev/null +++ b/arch/m32r/kernel/io_usrv.c | |||
@@ -0,0 +1,249 @@ | |||
1 | /* | ||
2 | * linux/arch/m32r/kernel/io_usrv.c | ||
3 | * | ||
4 | * Typical I/O routines for uServer board. | ||
5 | * | ||
6 | * Copyright (c) 2001 - 2003 Hiroyuki Kondo, Hirokazu Takata, | ||
7 | * Hitoshi Yamamoto, Takeo Takahashi | ||
8 | * | ||
9 | * This file is subject to the terms and conditions of the GNU General | ||
10 | * Public License. See the file "COPYING" in the main directory of this | ||
11 | * archive for more details. | ||
12 | * | ||
13 | */ | ||
14 | |||
15 | #include <linux/config.h> | ||
16 | #include <asm/m32r.h> | ||
17 | #include <asm/page.h> | ||
18 | #include <asm/io.h> | ||
19 | |||
20 | #include <linux/types.h> | ||
21 | #include "../drivers/m32r_cfc.h" | ||
22 | |||
23 | extern void pcc_ioread_byte(int, unsigned long, void *, size_t, size_t, int); | ||
24 | extern void pcc_ioread_word(int, unsigned long, void *, size_t, size_t, int); | ||
25 | extern void pcc_iowrite_byte(int, unsigned long, void *, size_t, size_t, int); | ||
26 | extern void pcc_iowrite_word(int, unsigned long, void *, size_t, size_t, int); | ||
27 | #define CFC_IOSTART CFC_IOPORT_BASE | ||
28 | #define CFC_IOEND (CFC_IOSTART + (M32R_PCC_MAPSIZE * M32R_MAX_PCC) - 1) | ||
29 | |||
30 | #if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE) | ||
31 | #define UART0_REGSTART 0x04c20000 | ||
32 | #define UART1_REGSTART 0x04c20100 | ||
33 | #define UART_IOMAP_SIZE 8 | ||
34 | #define UART0_IOSTART 0x3f8 | ||
35 | #define UART0_IOEND (UART0_IOSTART + UART_IOMAP_SIZE - 1) | ||
36 | #define UART1_IOSTART 0x2f8 | ||
37 | #define UART1_IOEND (UART1_IOSTART + UART_IOMAP_SIZE - 1) | ||
38 | #endif /* CONFIG_SERIAL_8250 || CONFIG_SERIAL_8250_MODULE */ | ||
39 | |||
40 | #define PORT2ADDR(port) _port2addr(port) | ||
41 | |||
42 | static __inline__ void *_port2addr(unsigned long port) | ||
43 | { | ||
44 | #if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE) | ||
45 | if (port >= UART0_IOSTART && port <= UART0_IOEND) | ||
46 | port = ((port - UART0_IOSTART) << 1) + UART0_REGSTART; | ||
47 | else if (port >= UART1_IOSTART && port <= UART1_IOEND) | ||
48 | port = ((port - UART1_IOSTART) << 1) + UART1_REGSTART; | ||
49 | #endif /* CONFIG_SERIAL_8250 || CONFIG_SERIAL_8250_MODULE */ | ||
50 | return (void *)(port + NONCACHE_OFFSET); | ||
51 | } | ||
52 | |||
53 | static __inline__ void delay(void) | ||
54 | { | ||
55 | __asm__ __volatile__ ("push r0; \n\t pop r0;" : : :"memory"); | ||
56 | } | ||
57 | |||
58 | unsigned char _inb(unsigned long port) | ||
59 | { | ||
60 | if (port >= CFC_IOSTART && port <= CFC_IOEND) { | ||
61 | unsigned char b; | ||
62 | pcc_ioread_byte(0, port, &b, sizeof(b), 1, 0); | ||
63 | return b; | ||
64 | } else | ||
65 | return *(volatile unsigned char *)PORT2ADDR(port); | ||
66 | } | ||
67 | |||
68 | unsigned short _inw(unsigned long port) | ||
69 | { | ||
70 | if (port >= CFC_IOSTART && port <= CFC_IOEND) { | ||
71 | unsigned short w; | ||
72 | pcc_ioread_word(0, port, &w, sizeof(w), 1, 0); | ||
73 | return w; | ||
74 | } else | ||
75 | return *(volatile unsigned short *)PORT2ADDR(port); | ||
76 | } | ||
77 | |||
78 | unsigned long _inl(unsigned long port) | ||
79 | { | ||
80 | if (port >= CFC_IOSTART && port <= CFC_IOEND) { | ||
81 | unsigned long l; | ||
82 | pcc_ioread_word(0, port, &l, sizeof(l), 1, 0); | ||
83 | return l; | ||
84 | } else | ||
85 | return *(volatile unsigned long *)PORT2ADDR(port); | ||
86 | } | ||
87 | |||
88 | unsigned char _inb_p(unsigned long port) | ||
89 | { | ||
90 | unsigned char b; | ||
91 | |||
92 | if (port >= CFC_IOSTART && port <= CFC_IOEND) { | ||
93 | pcc_ioread_byte(0, port, &b, sizeof(b), 1, 0); | ||
94 | return b; | ||
95 | } else { | ||
96 | b = *(volatile unsigned char *)PORT2ADDR(port); | ||
97 | delay(); | ||
98 | return b; | ||
99 | } | ||
100 | } | ||
101 | |||
102 | unsigned short _inw_p(unsigned long port) | ||
103 | { | ||
104 | unsigned short w; | ||
105 | |||
106 | if (port >= CFC_IOSTART && port <= CFC_IOEND) { | ||
107 | pcc_ioread_word(0, port, &w, sizeof(w), 1, 0); | ||
108 | return w; | ||
109 | } else { | ||
110 | w = *(volatile unsigned short *)PORT2ADDR(port); | ||
111 | delay(); | ||
112 | return w; | ||
113 | } | ||
114 | } | ||
115 | |||
116 | unsigned long _inl_p(unsigned long port) | ||
117 | { | ||
118 | unsigned long v; | ||
119 | |||
120 | v = *(volatile unsigned long *)PORT2ADDR(port); | ||
121 | delay(); | ||
122 | |||
123 | return v; | ||
124 | } | ||
125 | |||
126 | void _outb(unsigned char b, unsigned long port) | ||
127 | { | ||
128 | if (port >= CFC_IOSTART && port <= CFC_IOEND) | ||
129 | pcc_iowrite_byte(0, port, &b, sizeof(b), 1, 0); | ||
130 | else | ||
131 | *(volatile unsigned char *)PORT2ADDR(port) = b; | ||
132 | } | ||
133 | |||
134 | void _outw(unsigned short w, unsigned long port) | ||
135 | { | ||
136 | if (port >= CFC_IOSTART && port <= CFC_IOEND) | ||
137 | pcc_iowrite_word(0, port, &w, sizeof(w), 1, 0); | ||
138 | else | ||
139 | *(volatile unsigned short *)PORT2ADDR(port) = w; | ||
140 | } | ||
141 | |||
142 | void _outl(unsigned long l, unsigned long port) | ||
143 | { | ||
144 | if (port >= CFC_IOSTART && port <= CFC_IOEND) | ||
145 | pcc_iowrite_word(0, port, &l, sizeof(l), 1, 0); | ||
146 | else | ||
147 | *(volatile unsigned long *)PORT2ADDR(port) = l; | ||
148 | } | ||
149 | |||
150 | void _outb_p(unsigned char b, unsigned long port) | ||
151 | { | ||
152 | if (port >= CFC_IOSTART && port <= CFC_IOEND) | ||
153 | pcc_iowrite_byte(0, port, &b, sizeof(b), 1, 0); | ||
154 | else | ||
155 | *(volatile unsigned char *)PORT2ADDR(port) = b; | ||
156 | delay(); | ||
157 | } | ||
158 | |||
159 | void _outw_p(unsigned short w, unsigned long port) | ||
160 | { | ||
161 | if (port >= CFC_IOSTART && port <= CFC_IOEND) | ||
162 | pcc_iowrite_word(0, port, &w, sizeof(w), 1, 0); | ||
163 | else | ||
164 | *(volatile unsigned short *)PORT2ADDR(port) = w; | ||
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 >= CFC_IOSTART && port <= CFC_IOEND) | ||
177 | pcc_ioread_byte(0, port, addr, sizeof(unsigned char), count, 1); | ||
178 | else { | ||
179 | unsigned char *buf = addr; | ||
180 | unsigned char *portp = PORT2ADDR(port); | ||
181 | while (count--) | ||
182 | *buf++ = *(volatile unsigned char *)portp; | ||
183 | } | ||
184 | } | ||
185 | |||
186 | void _insw(unsigned int port, void * addr, unsigned long count) | ||
187 | { | ||
188 | unsigned short *buf = addr; | ||
189 | unsigned short *portp; | ||
190 | |||
191 | if (port >= CFC_IOSTART && port <= CFC_IOEND) | ||
192 | pcc_ioread_word(0, port, addr, sizeof(unsigned short), count, | ||
193 | 1); | ||
194 | else { | ||
195 | portp = PORT2ADDR(port); | ||
196 | while (count--) | ||
197 | *buf++ = *(volatile unsigned short *)portp; | ||
198 | } | ||
199 | } | ||
200 | |||
201 | void _insl(unsigned int port, void * addr, unsigned long count) | ||
202 | { | ||
203 | unsigned long *buf = addr; | ||
204 | unsigned long *portp; | ||
205 | |||
206 | portp = PORT2ADDR(port); | ||
207 | while (count--) | ||
208 | *buf++ = *(volatile unsigned long *)portp; | ||
209 | } | ||
210 | |||
211 | void _outsb(unsigned int port, const void * addr, unsigned long count) | ||
212 | { | ||
213 | const unsigned char *buf = addr; | ||
214 | unsigned char *portp; | ||
215 | |||
216 | if (port >= CFC_IOSTART && port <= CFC_IOEND) | ||
217 | pcc_iowrite_byte(0, port, (void *)addr, sizeof(unsigned char), | ||
218 | count, 1); | ||
219 | else { | ||
220 | portp = PORT2ADDR(port); | ||
221 | while (count--) | ||
222 | *(volatile unsigned char *)portp = *buf++; | ||
223 | } | ||
224 | } | ||
225 | |||
226 | void _outsw(unsigned int port, const void * addr, unsigned long count) | ||
227 | { | ||
228 | const unsigned short *buf = addr; | ||
229 | unsigned short *portp; | ||
230 | |||
231 | if (port >= CFC_IOSTART && port <= CFC_IOEND) | ||
232 | pcc_iowrite_word(0, port, (void *)addr, sizeof(unsigned short), | ||
233 | count, 1); | ||
234 | else { | ||
235 | portp = PORT2ADDR(port); | ||
236 | while (count--) | ||
237 | *(volatile unsigned short *)portp = *buf++; | ||
238 | } | ||
239 | } | ||
240 | |||
241 | void _outsl(unsigned int port, const void * addr, unsigned long count) | ||
242 | { | ||
243 | const unsigned long *buf = addr; | ||
244 | unsigned char *portp; | ||
245 | |||
246 | portp = PORT2ADDR(port); | ||
247 | while (count--) | ||
248 | *(volatile unsigned long *)portp = *buf++; | ||
249 | } | ||