[ubicom32]: move new files out from platform support patch
[openwrt/svn-archive/archive.git] / target / linux / ubicom32 / files / arch / ubicom32 / mach-common / io.c
1 /*
2 * arch/ubicom32/mach-common/io.c
3 * PCI I/O memory read/write support functions.
4 *
5 * (C) Copyright 2009, Ubicom, Inc.
6 *
7 * This file is part of the Ubicom32 Linux Kernel Port.
8 *
9 * The Ubicom32 Linux Kernel Port is free software: you can redistribute
10 * it and/or modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation, either version 2 of the
12 * License, or (at your option) any later version.
13 *
14 * The Ubicom32 Linux Kernel Port is distributed in the hope that it
15 * will be useful, but WITHOUT ANY WARRANTY; without even the implied
16 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
17 * the GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with the Ubicom32 Linux Kernel Port. If not,
21 * see <http://www.gnu.org/licenses/>.
22 *
23 * Ubicom32 implementation derived from (with many thanks):
24 * arch/m68knommu
25 * arch/blackfin
26 * arch/parisc
27 */
28 #include <linux/module.h>
29 #include <linux/kernel.h>
30 #include <linux/io.h>
31
32 #ifdef CONFIG_PCI
33 unsigned char ioread8(void __iomem *addr)
34 {
35 if (IS_PCI_ADDRESS(addr))
36 return ubi32_pci_read_u8(addr);
37 else
38 return (unsigned char)(*(volatile unsigned char *)addr);
39 }
40 EXPORT_SYMBOL(ioread8);
41
42 unsigned short ioread16(void __iomem *addr)
43 {
44 if (IS_PCI_ADDRESS(addr))
45 return ubi32_pci_read_u16(addr);
46 else
47 return (unsigned short)(*(volatile unsigned short *)addr);
48 }
49 EXPORT_SYMBOL(ioread16);
50
51 unsigned int ioread32(void __iomem *addr)
52 {
53 if (IS_PCI_ADDRESS(addr))
54 return ubi32_pci_read_u32(addr);
55 else
56 return (unsigned int)(*(volatile unsigned int *)addr);
57 }
58 EXPORT_SYMBOL(ioread32);
59
60 void iowrite32(unsigned int val, void __iomem *addr)
61 {
62 if (IS_PCI_ADDRESS(addr))
63 ubi32_pci_write_u32(val, addr);
64 else
65 *(volatile unsigned int *)addr = val;
66 }
67 EXPORT_SYMBOL(iowrite32);
68
69 void iowrite16(unsigned short val, void __iomem *addr)
70 {
71 if (IS_PCI_ADDRESS(addr))
72 ubi32_pci_write_u16(val, addr);
73 else
74 *(volatile unsigned short *)addr = val;
75 }
76 EXPORT_SYMBOL(iowrite16);
77
78 void iowrite8(unsigned char val, void __iomem *addr)
79 {
80 if (IS_PCI_ADDRESS(addr))
81 ubi32_pci_write_u8(val, addr);
82 else
83 *(volatile unsigned char *)addr = val;
84 }
85 EXPORT_SYMBOL(iowrite8);
86
87 void memcpy_fromio(void *to, const volatile void __iomem *from, unsigned len)
88 {
89 if (IS_PCI_ADDRESS(from)) {
90 if ((((u32_t)from & 0x3) == 0) && (((u32_t)to & 0x3) == 0)) {
91 while ((int)len >= 4) {
92 *(u32_t *)to = ubi32_pci_read_u32(from);
93 to += 4;
94 from += 4;
95 len -= 4;
96 }
97 } else if ((((u32_t)from & 0x1) == 0) &&
98 (((u32_t)to & 0x1) == 0)) {
99 while ((int)len >= 2) {
100 *(u16_t *)to = ubi32_pci_read_u16(from);
101 to += 2;
102 from += 2;
103 len -= 2;
104 }
105 }
106
107 while (len) {
108 *(u8_t *)to = ubi32_pci_read_u8(from);
109 to++;
110 from++;
111 len--;
112 }
113 } else
114 memcpy(to, (void *)from, len);
115 }
116 EXPORT_SYMBOL(memcpy_fromio);
117
118 void memcpy_toio(volatile void __iomem *to, const void *from, unsigned len)
119 {
120 if (IS_PCI_ADDRESS(to)) {
121 if ((((u32_t)from & 0x3) == 0) && (((u32_t)to & 0x3) == 0)) {
122 while ((int)len >= 4) {
123 ubi32_pci_write_u32(*(u32_t *)from, to);
124 to += 4;
125 from += 4;
126 len -= 4;
127 }
128 } else if ((((u32_t)from & 0x1) == 0) &&
129 (((u32_t)to & 0x1) == 0)) {
130 while ((int)len >= 2) {
131 ubi32_pci_write_u16(*(u16_t *)from, to);
132 to += 2;
133 from += 2;
134 len -= 2;
135 }
136 }
137
138 while (len) {
139 ubi32_pci_write_u8(*(u8_t *)from, to);
140 from++;
141 to++;
142 len--;
143 }
144 } else
145 memcpy((void *)to, from, len);
146
147 }
148 EXPORT_SYMBOL(memcpy_toio);
149
150 void memset_io(volatile void __iomem *addr, int val, size_t len)
151 {
152 if (IS_PCI_ADDRESS(addr)) {
153 while (len) {
154 ubi32_pci_write_u8((unsigned char)val, addr);
155 addr++;
156 len--;
157 }
158 } else
159 memset((void *)addr, val, len);
160
161 }
162 EXPORT_SYMBOL(memset_io);
163
164 void ioread8_rep(void __iomem *port, void *buf, unsigned long count)
165 {
166 if (IS_PCI_ADDRESS(port)) {
167 while (count) {
168 *(u8_t *)buf = ioread8(port);
169 buf++;
170 count--;
171 }
172 } else {
173 insb((unsigned int)port, buf, count);
174 }
175
176 }
177 EXPORT_SYMBOL(ioread8_rep);
178
179 void ioread16_rep(void __iomem *port, void *buf, unsigned long count)
180 {
181 if (IS_PCI_ADDRESS(port)) {
182 while (count) {
183 *(u16_t *)buf = ioread16(port);
184 buf += 2;
185 count--;
186 }
187 } else {
188 insw((unsigned int)port, buf, count);
189 }
190 }
191 EXPORT_SYMBOL(ioread16_rep);
192
193 void ioread32_rep(void __iomem *port, void *buf, unsigned long count)
194 {
195 if (IS_PCI_ADDRESS(port)) {
196 while (count) {
197 *(u32_t *)buf = ioread32(port);
198 buf += 4;
199 count--;
200 }
201 } else {
202 insl((unsigned int)port, buf, count);
203 }
204 }
205 EXPORT_SYMBOL(ioread32_rep);
206
207 void iowrite8_rep(void __iomem *port, const void *buf, unsigned long count)
208 {
209 if (IS_PCI_ADDRESS(port)) {
210 while (count) {
211 iowrite8(*(u8_t *)buf, port);
212 buf++;
213 count--;
214 }
215 } else {
216 outsb((unsigned int)port, buf, count);
217 }
218
219 }
220 EXPORT_SYMBOL(iowrite8_rep);
221
222 void iowrite16_rep(void __iomem *port, const void *buf, unsigned long count)
223 {
224 if (IS_PCI_ADDRESS(port)) {
225 while (count) {
226 iowrite16(*(u16_t *)buf, port);
227 buf += 2;
228 count--;
229 }
230 } else {
231 outsw((unsigned int)port, buf, count);
232 }
233 }
234 EXPORT_SYMBOL(iowrite16_rep);
235
236 void iowrite32_rep(void __iomem *port, const void *buf, unsigned long count)
237 {
238 if (IS_PCI_ADDRESS(port)) {
239 while (count) {
240 iowrite32(*(u32_t *)buf, port);
241 buf += 4;
242 count--;
243 }
244 } else {
245 outsl((unsigned int)port, buf, count);
246 }
247 }
248 EXPORT_SYMBOL(iowrite32_rep);
249
250 #endif /* CONFIG_PCI */