1
2#include <linux/module.h>
3#include <linux/kernel.h>
4#include <linux/types.h>
5
6#include <asm/hardware.h>
7#include <asm/io.h>
8#include <asm/page.h>
9
10static void __iomem *__isamem_convert_addr(const volatile void __iomem *addr)
11{
12	u32 ret, a = (u32 __force) addr;
13
14	/*
15	 * The PCMCIA controller is wired up as follows:
16	 *        +---------+---------+---------+---------+---------+---------+
17	 * PCMCIA | 2 2 2 2 | 1 1 1 1 | 1 1 1 1 | 1 1     |         |         |
18	 *        | 3 2 1 0 | 9 8 7 6 | 5 4 3 2 | 1 0 9 8 | 7 6 5 4 | 3 2 1 0 |
19	 *        +---------+---------+---------+---------+---------+---------+
20	 *  CPU   | 2 2 2 2 | 2 1 1 1 | 1 1 1 1 | 1 1 1   |         |         |
21	 *        | 4 3 2 1 | 0 9 9 8 | 7 6 5 4 | 3 2 0 9 | 8 7 6 5 | 4 3 2 x |
22	 *        +---------+---------+---------+---------+---------+---------+
23	 *
24	 * This means that we can access PCMCIA regions as follows:
25	 *	0x*10000 -> 0x*1ffff
26	 *	0x*70000 -> 0x*7ffff
27	 *	0x*90000 -> 0x*9ffff
28	 *	0x*f0000 -> 0x*fffff
29	 */
30	ret  = (a & 0xf803fe) << 1;
31	ret |= (a & 0x03fc00) << 2;
32
33	ret += 0xe8000000;
34
35	if ((a & 0x20000) == (a & 0x40000) >> 1)
36		return (void __iomem *)ret;
37
38	BUG();
39	return NULL;
40}
41
42/*
43 * read[bwl] and write[bwl]
44 */
45u8 __readb(const volatile void __iomem *addr)
46{
47	void __iomem *a = __isamem_convert_addr(addr);
48	u32 ret;
49
50	if ((unsigned long)addr & 1)
51		ret = __raw_readl(a);
52	else
53		ret = __raw_readb(a);
54	return ret;
55}
56
57u16 __readw(const volatile void __iomem *addr)
58{
59	void __iomem *a = __isamem_convert_addr(addr);
60
61	if ((unsigned long)addr & 1)
62		BUG();
63
64	return __raw_readw(a);
65}
66
67u32 __readl(const volatile void __iomem *addr)
68{
69	void __iomem *a = __isamem_convert_addr(addr);
70	u32 ret;
71
72	if ((unsigned long)addr & 3)
73		BUG();
74
75	ret = __raw_readw(a);
76	ret |= __raw_readw(a + 4) << 16;
77	return ret;
78}
79
80EXPORT_SYMBOL(__readb);
81EXPORT_SYMBOL(__readw);
82EXPORT_SYMBOL(__readl);
83
84void readsw(const void __iomem *addr, void *data, int len)
85{
86	void __iomem *a = __isamem_convert_addr(addr);
87
88	BUG_ON((unsigned long)addr & 1);
89
90	__raw_readsw(a, data, len);
91}
92EXPORT_SYMBOL(readsw);
93
94void readsl(const void __iomem *addr, void *data, int len)
95{
96	void __iomem *a = __isamem_convert_addr(addr);
97
98	BUG_ON((unsigned long)addr & 3);
99
100	__raw_readsl(a, data, len);
101}
102EXPORT_SYMBOL(readsl);
103
104void __writeb(u8 val, void __iomem *addr)
105{
106	void __iomem *a = __isamem_convert_addr(addr);
107
108	if ((unsigned long)addr & 1)
109		__raw_writel(val, a);
110	else
111		__raw_writeb(val, a);
112}
113
114void __writew(u16 val, void __iomem *addr)
115{
116	void __iomem *a = __isamem_convert_addr(addr);
117
118	if ((unsigned long)addr & 1)
119		BUG();
120
121	__raw_writew(val, a);
122}
123
124void __writel(u32 val, void __iomem *addr)
125{
126	void __iomem *a = __isamem_convert_addr(addr);
127
128	if ((unsigned long)addr & 3)
129		BUG();
130
131	__raw_writew(val, a);
132	__raw_writew(val >> 16, a + 4);
133}
134
135EXPORT_SYMBOL(__writeb);
136EXPORT_SYMBOL(__writew);
137EXPORT_SYMBOL(__writel);
138
139void writesw(void __iomem *addr, const void *data, int len)
140{
141	void __iomem *a = __isamem_convert_addr(addr);
142
143	BUG_ON((unsigned long)addr & 1);
144
145	__raw_writesw(a, data, len);
146}
147EXPORT_SYMBOL(writesw);
148
149void writesl(void __iomem *addr, const void *data, int len)
150{
151	void __iomem *a = __isamem_convert_addr(addr);
152
153	BUG_ON((unsigned long)addr & 3);
154
155	__raw_writesl(a, data, len);
156}
157EXPORT_SYMBOL(writesl);
158
159#define SUPERIO_PORT(p) \
160	(((p) >> 3) == (0x3f8 >> 3) || \
161	 ((p) >> 3) == (0x2f8 >> 3) || \
162	 ((p) >> 3) == (0x378 >> 3))
163
164/*
165 * We're addressing an 8 or 16-bit peripheral which tranfers
166 * odd addresses on the low ISA byte lane.
167 */
168u8 __inb8(unsigned int port)
169{
170	u32 ret;
171
172	/*
173	 * The SuperIO registers use sane addressing techniques...
174	 */
175	if (SUPERIO_PORT(port))
176		ret = __raw_readb((void __iomem *)ISAIO_BASE + (port << 2));
177	else {
178		void __iomem *a = (void __iomem *)ISAIO_BASE + ((port & ~1) << 1);
179
180		/*
181		 * Shame nothing else does
182		 */
183		if (port & 1)
184			ret = __raw_readl(a);
185		else
186			ret = __raw_readb(a);
187	}
188	return ret;
189}
190
191/*
192 * We're addressing a 16-bit peripheral which transfers odd
193 * addresses on the high ISA byte lane.
194 */
195u8 __inb16(unsigned int port)
196{
197	unsigned int offset;
198
199	/*
200	 * The SuperIO registers use sane addressing techniques...
201	 */
202	if (SUPERIO_PORT(port))
203		offset = port << 2;
204	else
205		offset = (port & ~1) << 1 | (port & 1);
206
207	return __raw_readb((void __iomem *)ISAIO_BASE + offset);
208}
209
210u16 __inw(unsigned int port)
211{
212	unsigned int offset;
213
214	/*
215	 * The SuperIO registers use sane addressing techniques...
216	 */
217	if (SUPERIO_PORT(port))
218		offset = port << 2;
219	else {
220		offset = port << 1;
221		BUG_ON(port & 1);
222	}
223	return __raw_readw((void __iomem *)ISAIO_BASE + offset);
224}
225
226/*
227 * Fake a 32-bit read with two 16-bit reads.  Needed for 3c589.
228 */
229u32 __inl(unsigned int port)
230{
231	void __iomem *a;
232
233	if (SUPERIO_PORT(port) || port & 3)
234		BUG();
235
236	a = (void __iomem *)ISAIO_BASE + ((port & ~1) << 1);
237
238	return __raw_readw(a) | __raw_readw(a + 4) << 16;
239}
240
241EXPORT_SYMBOL(__inb8);
242EXPORT_SYMBOL(__inb16);
243EXPORT_SYMBOL(__inw);
244EXPORT_SYMBOL(__inl);
245
246void __outb8(u8 val, unsigned int port)
247{
248	/*
249	 * The SuperIO registers use sane addressing techniques...
250	 */
251	if (SUPERIO_PORT(port))
252		__raw_writeb(val, (void __iomem *)ISAIO_BASE + (port << 2));
253	else {
254		void __iomem *a = (void __iomem *)ISAIO_BASE + ((port & ~1) << 1);
255
256		/*
257		 * Shame nothing else does
258		 */
259		if (port & 1)
260			__raw_writel(val, a);
261		else
262			__raw_writeb(val, a);
263	}
264}
265
266void __outb16(u8 val, unsigned int port)
267{
268	unsigned int offset;
269
270	/*
271	 * The SuperIO registers use sane addressing techniques...
272	 */
273	if (SUPERIO_PORT(port))
274		offset = port << 2;
275	else
276		offset = (port & ~1) << 1 | (port & 1);
277
278	__raw_writeb(val, (void __iomem *)ISAIO_BASE + offset);
279}
280
281void __outw(u16 val, unsigned int port)
282{
283	unsigned int offset;
284
285	/*
286	 * The SuperIO registers use sane addressing techniques...
287	 */
288	if (SUPERIO_PORT(port))
289		offset = port << 2;
290	else {
291		offset = port << 1;
292		BUG_ON(port & 1);
293	}
294	__raw_writew(val, (void __iomem *)ISAIO_BASE + offset);
295}
296
297void __outl(u32 val, unsigned int port)
298{
299	BUG();
300}
301
302EXPORT_SYMBOL(__outb8);
303EXPORT_SYMBOL(__outb16);
304EXPORT_SYMBOL(__outw);
305EXPORT_SYMBOL(__outl);
306
307void outsb(unsigned int port, const void *from, int len)
308{
309	u32 off;
310
311	if (SUPERIO_PORT(port))
312		off = port << 2;
313	else {
314		off = (port & ~1) << 1;
315		if (port & 1)
316			BUG();
317	}
318
319	__raw_writesb((void __iomem *)ISAIO_BASE + off, from, len);
320}
321
322void insb(unsigned int port, void *from, int len)
323{
324	u32 off;
325
326	if (SUPERIO_PORT(port))
327		off = port << 2;
328	else {
329		off = (port & ~1) << 1;
330		if (port & 1)
331			BUG();
332	}
333
334	__raw_readsb((void __iomem *)ISAIO_BASE + off, from, len);
335}
336
337EXPORT_SYMBOL(outsb);
338EXPORT_SYMBOL(insb);
339
340void outsw(unsigned int port, const void *from, int len)
341{
342	u32 off;
343
344	if (SUPERIO_PORT(port))
345		off = port << 2;
346	else {
347		off = (port & ~1) << 1;
348		if (port & 1)
349			BUG();
350	}
351
352	__raw_writesw((void __iomem *)ISAIO_BASE + off, from, len);
353}
354
355void insw(unsigned int port, void *from, int len)
356{
357	u32 off;
358
359	if (SUPERIO_PORT(port))
360		off = port << 2;
361	else {
362		off = (port & ~1) << 1;
363		if (port & 1)
364			BUG();
365	}
366
367	__raw_readsw((void __iomem *)ISAIO_BASE + off, from, len);
368}
369
370EXPORT_SYMBOL(outsw);
371EXPORT_SYMBOL(insw);
372
373/*
374 * We implement these as 16-bit insw/outsw, mainly for
375 * 3c589 cards.
376 */
377void outsl(unsigned int port, const void *from, int len)
378{
379	u32 off = port << 1;
380
381	if (SUPERIO_PORT(port) || port & 3)
382		BUG();
383
384	__raw_writesw((void __iomem *)ISAIO_BASE + off, from, len << 1);
385}
386
387void insl(unsigned int port, void *from, int len)
388{
389	u32 off = port << 1;
390
391	if (SUPERIO_PORT(port) || port & 3)
392		BUG();
393
394	__raw_readsw((void __iomem *)ISAIO_BASE + off, from, len << 1);
395}
396
397EXPORT_SYMBOL(outsl);
398EXPORT_SYMBOL(insl);
399