Linux-2.6.12-rc2
[linux-flexiantxendom0-natty.git] / arch / sh / kernel / io_generic.c
1 /* $Id: io_generic.c,v 1.2 2003/05/04 19:29:53 lethal Exp $
2  *
3  * linux/arch/sh/kernel/io_generic.c
4  *
5  * Copyright (C) 2000  Niibe Yutaka
6  *
7  * Generic I/O routine. These can be used where a machine specific version
8  * is not required.
9  *
10  * This file is subject to the terms and conditions of the GNU General Public
11  * License.  See the file "COPYING" in the main directory of this archive
12  * for more details.
13  *
14  */
15
16 #include <asm/io.h>
17 #include <asm/machvec.h>
18 #include <linux/module.h>
19
20 #if defined(CONFIG_CPU_SH3)
21 /* I'm not sure SH7709 has this kind of bug */
22 #define SH3_PCMCIA_BUG_WORKAROUND 1
23 #define DUMMY_READ_AREA6          0xba000000
24 #endif
25
26 #define PORT2ADDR(x) (sh_mv.mv_isa_port2addr(x))
27
28 unsigned long generic_io_base;
29
30 static inline void delay(void)
31 {
32         ctrl_inw(0xa0000000);
33 }
34
35 unsigned char generic_inb(unsigned long port)
36 {
37         return *(volatile unsigned char*)PORT2ADDR(port);
38 }
39
40 unsigned short generic_inw(unsigned long port)
41 {
42         return *(volatile unsigned short*)PORT2ADDR(port);
43 }
44
45 unsigned int generic_inl(unsigned long port)
46 {
47         return *(volatile unsigned long*)PORT2ADDR(port);
48 }
49
50 unsigned char generic_inb_p(unsigned long port)
51 {
52         unsigned long v = *(volatile unsigned char*)PORT2ADDR(port);
53
54         delay();
55         return v;
56 }
57
58 unsigned short generic_inw_p(unsigned long port)
59 {
60         unsigned long v = *(volatile unsigned short*)PORT2ADDR(port);
61
62         delay();
63         return v;
64 }
65
66 unsigned int generic_inl_p(unsigned long port)
67 {
68         unsigned long v = *(volatile unsigned long*)PORT2ADDR(port);
69
70         delay();
71         return v;
72 }
73
74 /*
75  * insb/w/l all read a series of bytes/words/longs from a fixed port
76  * address. However as the port address doesn't change we only need to
77  * convert the port address to real address once.
78  */
79
80 void generic_insb(unsigned long port, void *buffer, unsigned long count)
81 {
82         volatile unsigned char *port_addr;
83         unsigned char *buf=buffer;
84
85         port_addr = (volatile unsigned char *)PORT2ADDR(port);
86
87         while(count--)
88             *buf++ = *port_addr;
89 }
90
91 void generic_insw(unsigned long port, void *buffer, unsigned long count)
92 {
93         volatile unsigned short *port_addr;
94         unsigned short *buf=buffer;
95
96         port_addr = (volatile unsigned short *)PORT2ADDR(port);
97
98         while(count--)
99             *buf++ = *port_addr;
100 #ifdef SH3_PCMCIA_BUG_WORKAROUND
101         ctrl_inb (DUMMY_READ_AREA6);
102 #endif
103 }
104
105 void generic_insl(unsigned long port, void *buffer, unsigned long count)
106 {
107         volatile unsigned long *port_addr;
108         unsigned long *buf=buffer;
109
110         port_addr = (volatile unsigned long *)PORT2ADDR(port);
111
112         while(count--)
113             *buf++ = *port_addr;
114 #ifdef SH3_PCMCIA_BUG_WORKAROUND
115         ctrl_inb (DUMMY_READ_AREA6);
116 #endif
117 }
118
119 void generic_outb(unsigned char b, unsigned long port)
120 {
121         *(volatile unsigned char*)PORT2ADDR(port) = b;
122 }
123
124 void generic_outw(unsigned short b, unsigned long port)
125 {
126         *(volatile unsigned short*)PORT2ADDR(port) = b;
127 }
128
129 void generic_outl(unsigned int b, unsigned long port)
130 {
131         *(volatile unsigned long*)PORT2ADDR(port) = b;
132 }
133
134 void generic_outb_p(unsigned char b, unsigned long port)
135 {
136         *(volatile unsigned char*)PORT2ADDR(port) = b;
137         delay();
138 }
139
140 void generic_outw_p(unsigned short b, unsigned long port)
141 {
142         *(volatile unsigned short*)PORT2ADDR(port) = b;
143         delay();
144 }
145
146 void generic_outl_p(unsigned int b, unsigned long port)
147 {
148         *(volatile unsigned long*)PORT2ADDR(port) = b;
149         delay();
150 }
151
152 /*
153  * outsb/w/l all write a series of bytes/words/longs to a fixed port
154  * address. However as the port address doesn't change we only need to
155  * convert the port address to real address once.
156  */
157
158 void generic_outsb(unsigned long port, const void *buffer, unsigned long count)
159 {
160         volatile unsigned char *port_addr;
161         const unsigned char *buf=buffer;
162
163         port_addr = (volatile unsigned char *)PORT2ADDR(port);
164
165         while(count--)
166             *port_addr = *buf++;
167 }
168
169 void generic_outsw(unsigned long port, const void *buffer, unsigned long count)
170 {
171         volatile unsigned short *port_addr;
172         const unsigned short *buf=buffer;
173
174         port_addr = (volatile unsigned short *)PORT2ADDR(port);
175
176         while(count--)
177             *port_addr = *buf++;
178
179 #ifdef SH3_PCMCIA_BUG_WORKAROUND
180         ctrl_inb (DUMMY_READ_AREA6);
181 #endif
182 }
183
184 void generic_outsl(unsigned long port, const void *buffer, unsigned long count)
185 {
186         volatile unsigned long *port_addr;
187         const unsigned long *buf=buffer;
188
189         port_addr = (volatile unsigned long *)PORT2ADDR(port);
190
191         while(count--)
192             *port_addr = *buf++;
193
194 #ifdef SH3_PCMCIA_BUG_WORKAROUND
195         ctrl_inb (DUMMY_READ_AREA6);
196 #endif
197 }
198
199 unsigned char generic_readb(unsigned long addr)
200 {
201         return *(volatile unsigned char*)addr;
202 }
203
204 unsigned short generic_readw(unsigned long addr)
205 {
206         return *(volatile unsigned short*)addr;
207 }
208
209 unsigned int generic_readl(unsigned long addr)
210 {
211         return *(volatile unsigned long*)addr;
212 }
213
214 void generic_writeb(unsigned char b, unsigned long addr)
215 {
216         *(volatile unsigned char*)addr = b;
217 }
218
219 void generic_writew(unsigned short b, unsigned long addr)
220 {
221         *(volatile unsigned short*)addr = b;
222 }
223
224 void generic_writel(unsigned int b, unsigned long addr)
225 {
226         *(volatile unsigned long*)addr = b;
227 }
228
229 void * generic_ioremap(unsigned long offset, unsigned long size)
230 {
231         return (void *) P2SEGADDR(offset);
232 }
233 EXPORT_SYMBOL(generic_ioremap);
234
235 void generic_iounmap(void *addr)
236 {
237 }
238 EXPORT_SYMBOL(generic_iounmap);
239
240 unsigned long generic_isa_port2addr(unsigned long offset)
241 {
242         return offset + generic_io_base;
243 }