aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/boards/landisk/io.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sh/boards/landisk/io.c')
-rw-r--r--arch/sh/boards/landisk/io.c322
1 files changed, 322 insertions, 0 deletions
diff --git a/arch/sh/boards/landisk/io.c b/arch/sh/boards/landisk/io.c
new file mode 100644
index 000000000000..1f1679af09d0
--- /dev/null
+++ b/arch/sh/boards/landisk/io.c
@@ -0,0 +1,322 @@
1/*
2 * arch/sh/boards/landisk/io.c
3 *
4 * Copyright (C) 2001 Ian da Silva, Jeremy Siegel
5 * Based largely on io_se.c.
6 *
7 * I/O routine for I-O Data Device, Inc. LANDISK.
8 *
9 * Initial version only to support LAN access; some
10 * placeholder code from io_landisk.c left in with the
11 * expectation of later SuperIO and PCMCIA access.
12 */
13/*
14 * modifed by kogiidena
15 * 2005.03.03
16 */
17
18#include <linux/kernel.h>
19#include <linux/types.h>
20#include <asm/io.h>
21#include <asm/landisk/iodata_landisk.h>
22#include <asm/addrspace.h>
23
24#include <linux/module.h>
25#include <linux/pci.h>
26#include "../../drivers/pci/pci-sh7751.h"
27
28extern void *area5_io_base; /* Area 5 I/O Base address */
29extern void *area6_io_base; /* Area 6 I/O Base address */
30
31/*
32 * The 7751R LANDISK uses the built-in PCI controller (PCIC)
33 * of the 7751R processor, and has a SuperIO accessible via the PCI.
34 * The board also includes a PCMCIA controller on its memory bus,
35 * like the other Solution Engine boards.
36 */
37
38#define PCIIOBR (volatile long *)PCI_REG(SH7751_PCIIOBR)
39#define PCIMBR (volatile long *)PCI_REG(SH7751_PCIMBR)
40#define PCI_IO_AREA SH7751_PCI_IO_BASE
41#define PCI_MEM_AREA SH7751_PCI_CONFIG_BASE
42
43#define PCI_IOMAP(adr) (PCI_IO_AREA + (adr & ~SH7751_PCIIOBR_MASK))
44
45#define maybebadio(name,port) \
46 printk("bad PC-like io %s for port 0x%lx at 0x%08x\n", \
47 #name, (port), (__u32) __builtin_return_address(0))
48
49static inline void delay(void)
50{
51 ctrl_inw(0xa0000000);
52}
53
54static inline unsigned long port2adr(unsigned int port)
55{
56 if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6)
57 if (port == 0x3f6)
58 return ((unsigned long)area5_io_base + 0x2c);
59 else
60 return ((unsigned long)area5_io_base + PA_PIDE_OFFSET +
61 ((port - 0x1f0) << 1));
62 else if ((0x170 <= port && port < 0x178) || port == 0x376)
63 if (port == 0x376)
64 return ((unsigned long)area6_io_base + 0x2c);
65 else
66 return ((unsigned long)area6_io_base + PA_SIDE_OFFSET +
67 ((port - 0x170) << 1));
68 else
69 maybebadio(port2adr, (unsigned long)port);
70
71 return port;
72}
73
74/* In case someone configures the kernel w/o PCI support: in that */
75/* scenario, don't ever bother to check for PCI-window addresses */
76
77/* NOTE: WINDOW CHECK MAY BE A BIT OFF, HIGH PCIBIOS_MIN_IO WRAPS? */
78#if defined(CONFIG_PCI)
79#define CHECK_SH7751_PCIIO(port) \
80 ((port >= PCIBIOS_MIN_IO) && (port < (PCIBIOS_MIN_IO + SH7751_PCI_IO_SIZE)))
81#else
82#define CHECK_SH_7751_PCIIO(port) (0)
83#endif
84
85/*
86 * General outline: remap really low stuff [eventually] to SuperIO,
87 * stuff in PCI IO space (at or above window at pci.h:PCIBIOS_MIN_IO)
88 * is mapped through the PCI IO window. Stuff with high bits (PXSEG)
89 * should be way beyond the window, and is used w/o translation for
90 * compatibility.
91 */
92unsigned char landisk_inb(unsigned long port)
93{
94 if (PXSEG(port))
95 return *(volatile unsigned char *)port;
96 else if (CHECK_SH7751_PCIIO(port))
97 return *(volatile unsigned char *)PCI_IOMAP(port);
98 else
99 return (*(volatile unsigned short *)port2adr(port) & 0xff);
100}
101
102unsigned char landisk_inb_p(unsigned long port)
103{
104 unsigned char v;
105
106 if (PXSEG(port))
107 v = *(volatile unsigned char *)port;
108 else if (CHECK_SH7751_PCIIO(port))
109 v = *(volatile unsigned char *)PCI_IOMAP(port);
110 else
111 v = (*(volatile unsigned short *)port2adr(port) & 0xff);
112 delay();
113
114 return v;
115}
116
117unsigned short landisk_inw(unsigned long port)
118{
119 if (PXSEG(port))
120 return *(volatile unsigned short *)port;
121 else if (CHECK_SH7751_PCIIO(port))
122 return *(volatile unsigned short *)PCI_IOMAP(port);
123 else
124 maybebadio(inw, port);
125
126 return 0;
127}
128
129unsigned int landisk_inl(unsigned long port)
130{
131 if (PXSEG(port))
132 return *(volatile unsigned long *)port;
133 else if (CHECK_SH7751_PCIIO(port))
134 return *(volatile unsigned long *)PCI_IOMAP(port);
135 else
136 maybebadio(inl, port);
137
138 return 0;
139}
140
141void landisk_outb(unsigned char value, unsigned long port)
142{
143
144 if (PXSEG(port))
145 *(volatile unsigned char *)port = value;
146 else if (CHECK_SH7751_PCIIO(port))
147 *(volatile unsigned char *)PCI_IOMAP(port) = value;
148 else
149 *(volatile unsigned short *)port2adr(port) = value;
150}
151
152void landisk_outb_p(unsigned char value, unsigned long port)
153{
154 if (PXSEG(port))
155 *(volatile unsigned char *)port = value;
156 else if (CHECK_SH7751_PCIIO(port))
157 *(volatile unsigned char *)PCI_IOMAP(port) = value;
158 else
159 *(volatile unsigned short *)port2adr(port) = value;
160 delay();
161}
162
163void landisk_outw(unsigned short value, unsigned long port)
164{
165 if (PXSEG(port))
166 *(volatile unsigned short *)port = value;
167 else if (CHECK_SH7751_PCIIO(port))
168 *(volatile unsigned short *)PCI_IOMAP(port) = value;
169 else
170 maybebadio(outw, port);
171}
172
173void landisk_outl(unsigned int value, unsigned long port)
174{
175 if (PXSEG(port))
176 *(volatile unsigned long *)port = value;
177 else if (CHECK_SH7751_PCIIO(port))
178 *(volatile unsigned long *)PCI_IOMAP(port) = value;
179 else
180 maybebadio(outl, port);
181}
182
183void landisk_insb(unsigned long port, void *addr, unsigned long count)
184{
185 if (PXSEG(port))
186 while (count--)
187 *((unsigned char *)addr)++ =
188 *(volatile unsigned char *)port;
189 else if (CHECK_SH7751_PCIIO(port)) {
190 volatile __u8 *bp = (__u8 *) PCI_IOMAP(port);
191
192 while (count--)
193 *((volatile unsigned char *)addr)++ = *bp;
194 } else {
195 volatile __u16 *p = (volatile unsigned short *)port2adr(port);
196
197 while (count--)
198 *((unsigned char *)addr)++ = *p;
199 }
200}
201
202void landisk_insw(unsigned long port, void *addr, unsigned long count)
203{
204 volatile __u16 *p;
205
206 if (PXSEG(port))
207 p = (volatile unsigned short *)port;
208 else if (CHECK_SH7751_PCIIO(port))
209 p = (volatile unsigned short *)PCI_IOMAP(port);
210 else
211 p = (volatile unsigned short *)port2adr(port);
212 while (count--)
213 *((__u16 *) addr)++ = *p;
214}
215
216void landisk_insl(unsigned long port, void *addr, unsigned long count)
217{
218 if (CHECK_SH7751_PCIIO(port)) {
219 volatile __u32 *p = (__u32 *) PCI_IOMAP(port);
220
221 while (count--)
222 *((__u32 *) addr)++ = *p;
223 } else
224 maybebadio(insl, port);
225}
226
227void landisk_outsb(unsigned long port, const void *addr, unsigned long count)
228{
229 if (PXSEG(port))
230 while (count--)
231 *(volatile unsigned char *)port =
232 *((unsigned char *)addr)++;
233 else if (CHECK_SH7751_PCIIO(port)) {
234 volatile __u8 *bp = (__u8 *) PCI_IOMAP(port);
235
236 while (count--)
237 *bp = *((volatile unsigned char *)addr)++;
238 } else {
239 volatile __u16 *p = (volatile unsigned short *)port2adr(port);
240
241 while (count--)
242 *p = *((unsigned char *)addr)++;
243 }
244}
245
246void landisk_outsw(unsigned long port, const void *addr, unsigned long count)
247{
248 volatile __u16 *p;
249
250 if (PXSEG(port))
251 p = (volatile unsigned short *)port;
252 else if (CHECK_SH7751_PCIIO(port))
253 p = (volatile unsigned short *)PCI_IOMAP(port);
254 else
255 p = (volatile unsigned short *)port2adr(port);
256 while (count--)
257 *p = *((__u16 *) addr)++;
258}
259
260void landisk_outsl(unsigned long port, const void *addr, unsigned long count)
261{
262 if (CHECK_SH7751_PCIIO(port)) {
263 volatile __u32 *p = (__u32 *) PCI_IOMAP(port);
264
265 while (count--)
266 *p = *((__u32 *) addr)++;
267 } else
268 maybebadio(outsl, port);
269}
270
271/* For read/write calls, just copy generic (pass-thru); PCIMBR is */
272/* already set up. For a larger memory space, these would need to */
273/* reset PCIMBR as needed on a per-call basis... */
274
275unsigned char landisk_readb(unsigned long addr)
276{
277 return *(volatile unsigned char *)addr;
278}
279
280unsigned short landisk_readw(unsigned long addr)
281{
282 return *(volatile unsigned short *)addr;
283}
284
285unsigned int landisk_readl(unsigned long addr)
286{
287 return *(volatile unsigned long *)addr;
288}
289
290void landisk_writeb(unsigned char b, unsigned long addr)
291{
292 *(volatile unsigned char *)addr = b;
293}
294
295void landisk_writew(unsigned short b, unsigned long addr)
296{
297 *(volatile unsigned short *)addr = b;
298}
299
300void landisk_writel(unsigned int b, unsigned long addr)
301{
302 *(volatile unsigned long *)addr = b;
303}
304
305void *landisk_ioremap(unsigned long offset, unsigned long size)
306{
307 if (offset >= 0xfd000000)
308 return (void *)offset;
309 else
310 return (void *)P2SEGADDR(offset);
311}
312
313void landisk_iounmap(void *addr)
314{
315}
316
317/* Map ISA bus address to the real address. Only for PCMCIA. */
318
319unsigned long landisk_isa_port2addr(unsigned long offset)
320{
321 return port2adr(offset);
322}