Merge branch 'master' into upstream
[pandora-kernel.git] / arch / sh / boards / renesas / r7780rp / io.c
1 /*
2  * Copyright (C) 2001  Ian da Silva, Jeremy Siegel
3  * Based largely on io_se.c.
4  *
5  * I/O routine for Renesas Solutions Highlander R7780RP-1
6  *
7  * Initial version only to support LAN access; some
8  * placeholder code from io_r7780rp.c left in with the
9  * expectation of later SuperIO and PCMCIA access.
10  */
11 #include <linux/pci.h>
12 #include <linux/kernel.h>
13 #include <linux/types.h>
14 #include <linux/io.h>
15 #include <asm/r7780rp.h>
16 #include <asm/addrspace.h>
17
18 static inline unsigned long port88796l(unsigned int port, int flag)
19 {
20         unsigned long addr;
21
22         if (flag)
23                 addr = PA_AX88796L + ((port - AX88796L_IO_BASE) << 1);
24         else
25                 addr = PA_AX88796L + ((port - AX88796L_IO_BASE) << 1) + 0x1000;
26
27         return addr;
28 }
29
30 #if defined(CONFIG_NE2000) || defined(CONFIG_NE2000_MODULE)
31 #define CHECK_AX88796L_PORT(port) \
32   ((port >= AX88796L_IO_BASE) && (port < (AX88796L_IO_BASE+0x20)))
33 #else
34 #define CHECK_AX88796L_PORT(port) (0)
35 #endif
36
37 /*
38  * General outline: remap really low stuff [eventually] to SuperIO,
39  * stuff in PCI IO space (at or above window at pci.h:PCIBIOS_MIN_IO)
40  * is mapped through the PCI IO window.  Stuff with high bits (PXSEG)
41  * should be way beyond the window, and is used  w/o translation for
42  * compatibility.
43  */
44 u8 r7780rp_inb(unsigned long port)
45 {
46         if (CHECK_AX88796L_PORT(port))
47                 return ctrl_inw(port88796l(port, 0)) & 0xff;
48         else if (is_pci_ioaddr(port))
49                 return ctrl_inb(pci_ioaddr(port));
50
51         return ctrl_inw(port) & 0xff;
52 }
53
54 u8 r7780rp_inb_p(unsigned long port)
55 {
56         u8 v;
57
58         if (CHECK_AX88796L_PORT(port))
59                 v = ctrl_inw(port88796l(port, 0)) & 0xff;
60         else if (is_pci_ioaddr(port))
61                 v = ctrl_inb(pci_ioaddr(port));
62         else
63                 v = ctrl_inw(port) & 0xff;
64
65         ctrl_delay();
66
67         return v;
68 }
69
70 u16 r7780rp_inw(unsigned long port)
71 {
72         if (is_pci_ioaddr(port))
73                 return ctrl_inw(pci_ioaddr(port));
74
75         return ctrl_inw(port);
76 }
77
78 u32 r7780rp_inl(unsigned long port)
79 {
80         if (is_pci_ioaddr(port))
81                 return ctrl_inl(pci_ioaddr(port));
82
83         return ctrl_inl(port);
84 }
85
86 void r7780rp_outb(u8 value, unsigned long port)
87 {
88         if (CHECK_AX88796L_PORT(port))
89                 ctrl_outw(value, port88796l(port, 0));
90         else if (is_pci_ioaddr(port))
91                 ctrl_outb(value, pci_ioaddr(port));
92         else
93                 ctrl_outb(value, port);
94 }
95
96 void r7780rp_outb_p(u8 value, unsigned long port)
97 {
98         if (CHECK_AX88796L_PORT(port))
99                 ctrl_outw(value, port88796l(port, 0));
100         else if (is_pci_ioaddr(port))
101                 ctrl_outb(value, pci_ioaddr(port));
102         else
103                 ctrl_outb(value, port);
104
105         ctrl_delay();
106 }
107
108 void r7780rp_outw(u16 value, unsigned long port)
109 {
110         if (is_pci_ioaddr(port))
111                 ctrl_outw(value, pci_ioaddr(port));
112         else
113                 ctrl_outw(value, port);
114 }
115
116 void r7780rp_outl(u32 value, unsigned long port)
117 {
118         if (is_pci_ioaddr(port))
119                 ctrl_outl(value, pci_ioaddr(port));
120         else
121                 ctrl_outl(value, port);
122 }
123
124 void r7780rp_insb(unsigned long port, void *dst, unsigned long count)
125 {
126         volatile u16 *p;
127         u8 *buf = dst;
128
129         if (CHECK_AX88796L_PORT(port)) {
130                 p = (volatile u16 *)port88796l(port, 0);
131                 while (count--)
132                         *buf++ = *p & 0xff;
133         } else if (is_pci_ioaddr(port)) {
134                 volatile u8 *bp = (volatile u8 *)pci_ioaddr(port);
135
136                 while (count--)
137                         *buf++ = *bp;
138         } else {
139                 p = (volatile u16 *)port;
140                 while (count--)
141                         *buf++ = *p & 0xff;
142         }
143 }
144
145 void r7780rp_insw(unsigned long port, void *dst, unsigned long count)
146 {
147         volatile u16 *p;
148         u16 *buf = dst;
149
150         if (CHECK_AX88796L_PORT(port))
151                 p = (volatile u16 *)port88796l(port, 1);
152         else if (is_pci_ioaddr(port))
153                 p = (volatile u16 *)pci_ioaddr(port);
154         else
155                 p = (volatile u16 *)port;
156
157         while (count--)
158                 *buf++ = *p;
159
160         flush_dcache_all();
161 }
162
163 void r7780rp_insl(unsigned long port, void *dst, unsigned long count)
164 {
165         if (is_pci_ioaddr(port)) {
166                 volatile u32 *p = (volatile u32 *)pci_ioaddr(port);
167                 u32 *buf = dst;
168
169                 while (count--)
170                         *buf++ = *p;
171         }
172 }
173
174 void r7780rp_outsb(unsigned long port, const void *src, unsigned long count)
175 {
176         volatile u16 *p;
177         const u8 *buf = src;
178
179         if (CHECK_AX88796L_PORT(port)) {
180                 p = (volatile u16 *)port88796l(port, 0);
181                 while (count--)
182                         *p = *buf++;
183         } else if (is_pci_ioaddr(port)) {
184                 volatile u8 *bp = (volatile u8 *)pci_ioaddr(port);
185
186                 while (count--)
187                         *bp = *buf++;
188         } else
189                 while (count--)
190                         ctrl_outb(*buf++, port);
191 }
192
193 void r7780rp_outsw(unsigned long port, const void *src, unsigned long count)
194 {
195         volatile u16 *p;
196         const u16 *buf = src;
197
198         if (CHECK_AX88796L_PORT(port))
199                 p = (volatile u16 *)port88796l(port, 1);
200         else if (is_pci_ioaddr(port))
201                 p = (volatile u16 *)pci_ioaddr(port);
202         else
203                 p = (volatile u16 *)port;
204
205         while (count--)
206                 *p = *buf++;
207
208         flush_dcache_all();
209 }
210
211 void r7780rp_outsl(unsigned long port, const void *src, unsigned long count)
212 {
213         const u32 *buf = src;
214         u32 *p;
215
216         if (is_pci_ioaddr(port))
217                 p = (u32 *)pci_ioaddr(port);
218         else
219                 p = (u32 *)port;
220
221         while (count--)
222                 ctrl_outl(*buf++, (unsigned long)p);
223 }
224
225 void __iomem *r7780rp_ioport_map(unsigned long port, unsigned int size)
226 {
227         if (CHECK_AX88796L_PORT(port))
228                 return (void __iomem *)port88796l(port, size > 1);
229         else if (is_pci_ioaddr(port))
230                 return (void __iomem *)pci_ioaddr(port);
231
232         return (void __iomem *)port;
233 }