1 /* $Id: io_generic.c,v 1.12 2000/11/14 16:45:11 sugioka 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(__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
delay(void)30 static inline void delay(void)
31 {
32 ctrl_inw(0xa0000000);
33 }
34
generic_inb(unsigned long port)35 unsigned char generic_inb(unsigned long port)
36 {
37 return *(volatile unsigned char*)PORT2ADDR(port);
38 }
39
generic_inw(unsigned long port)40 unsigned short generic_inw(unsigned long port)
41 {
42 return *(volatile unsigned short*)PORT2ADDR(port);
43 }
44
generic_inl(unsigned long port)45 unsigned int generic_inl(unsigned long port)
46 {
47 return *(volatile unsigned long*)PORT2ADDR(port);
48 }
49
generic_inb_p(unsigned long port)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
generic_inw_p(unsigned long port)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
generic_inl_p(unsigned long port)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
generic_insb(unsigned long port,void * buffer,unsigned long count)74 void generic_insb(unsigned long port, void *buffer, unsigned long count)
75 {
76 unsigned char *buf=buffer;
77 while(count--) *buf++=inb(port);
78 }
79
generic_insw(unsigned long port,void * buffer,unsigned long count)80 void generic_insw(unsigned long port, void *buffer, unsigned long count)
81 {
82 unsigned short *buf=buffer;
83 while(count--) *buf++=inw(port);
84 #ifdef SH3_PCMCIA_BUG_WORKAROUND
85 ctrl_inb (DUMMY_READ_AREA6);
86 #endif
87 }
88
generic_insl(unsigned long port,void * buffer,unsigned long count)89 void generic_insl(unsigned long port, void *buffer, unsigned long count)
90 {
91 unsigned long *buf=buffer;
92 while(count--) *buf++=inl(port);
93 #ifdef SH3_PCMCIA_BUG_WORKAROUND
94 ctrl_inb (DUMMY_READ_AREA6);
95 #endif
96 }
97
generic_outb(unsigned char b,unsigned long port)98 void generic_outb(unsigned char b, unsigned long port)
99 {
100 *(volatile unsigned char*)PORT2ADDR(port) = b;
101 }
102
generic_outw(unsigned short b,unsigned long port)103 void generic_outw(unsigned short b, unsigned long port)
104 {
105 *(volatile unsigned short*)PORT2ADDR(port) = b;
106 }
107
generic_outl(unsigned int b,unsigned long port)108 void generic_outl(unsigned int b, unsigned long port)
109 {
110 *(volatile unsigned long*)PORT2ADDR(port) = b;
111 }
112
generic_outb_p(unsigned char b,unsigned long port)113 void generic_outb_p(unsigned char b, unsigned long port)
114 {
115 *(volatile unsigned char*)PORT2ADDR(port) = b;
116 delay();
117 }
118
generic_outw_p(unsigned short b,unsigned long port)119 void generic_outw_p(unsigned short b, unsigned long port)
120 {
121 *(volatile unsigned short*)PORT2ADDR(port) = b;
122 delay();
123 }
124
generic_outl_p(unsigned int b,unsigned long port)125 void generic_outl_p(unsigned int b, unsigned long port)
126 {
127 *(volatile unsigned long*)PORT2ADDR(port) = b;
128 delay();
129 }
130
generic_outsb(unsigned long port,const void * buffer,unsigned long count)131 void generic_outsb(unsigned long port, const void *buffer, unsigned long count)
132 {
133 const unsigned char *buf=buffer;
134 while(count--) outb(*buf++, port);
135 }
136
generic_outsw(unsigned long port,const void * buffer,unsigned long count)137 void generic_outsw(unsigned long port, const void *buffer, unsigned long count)
138 {
139 const unsigned short *buf=buffer;
140 while(count--) outw(*buf++, port);
141 #ifdef SH3_PCMCIA_BUG_WORKAROUND
142 ctrl_inb (DUMMY_READ_AREA6);
143 #endif
144 }
145
generic_outsl(unsigned long port,const void * buffer,unsigned long count)146 void generic_outsl(unsigned long port, const void *buffer, unsigned long count)
147 {
148 const unsigned long *buf=buffer;
149 while(count--) outl(*buf++, port);
150 #ifdef SH3_PCMCIA_BUG_WORKAROUND
151 ctrl_inb (DUMMY_READ_AREA6);
152 #endif
153 }
154
generic_readb(unsigned long addr)155 unsigned char generic_readb(unsigned long addr)
156 {
157 return *(volatile unsigned char*)addr;
158 }
159
generic_readw(unsigned long addr)160 unsigned short generic_readw(unsigned long addr)
161 {
162 return *(volatile unsigned short*)addr;
163 }
164
generic_readl(unsigned long addr)165 unsigned int generic_readl(unsigned long addr)
166 {
167 return *(volatile unsigned long*)addr;
168 }
169
generic_writeb(unsigned char b,unsigned long addr)170 void generic_writeb(unsigned char b, unsigned long addr)
171 {
172 *(volatile unsigned char*)addr = b;
173 }
174
generic_writew(unsigned short b,unsigned long addr)175 void generic_writew(unsigned short b, unsigned long addr)
176 {
177 *(volatile unsigned short*)addr = b;
178 }
179
generic_writel(unsigned int b,unsigned long addr)180 void generic_writel(unsigned int b, unsigned long addr)
181 {
182 *(volatile unsigned long*)addr = b;
183 }
184
generic_ioremap(unsigned long offset,unsigned long size)185 void * generic_ioremap(unsigned long offset, unsigned long size)
186 {
187 return (void *) P2SEGADDR(offset);
188 }
189 EXPORT_SYMBOL(generic_ioremap);
190
generic_iounmap(void * addr)191 void generic_iounmap(void *addr)
192 {
193 }
194 EXPORT_SYMBOL(generic_iounmap);
195
generic_isa_port2addr(unsigned long offset)196 unsigned long generic_isa_port2addr(unsigned long offset)
197 {
198 return offset + generic_io_base;
199 }
200