File: /usr/src/linux/arch/sh/kernel/io_generic.c

1     /* $Id: io_generic.c,v 1.3 2000/05/07 23:31:58 gniibe 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     
30     static inline void delay(void)
31     {
32     	ctrl_inw(0xa0000000);
33     }
34     
35     unsigned char generic_inb(unsigned long port)
36     {
37     	return *(volatile unsigned char*)PORT2ADDR(port);
38     }
39     
40     unsigned short generic_inw(unsigned long port)
41     {
42     	return *(volatile unsigned short*)PORT2ADDR(port);
43     }
44     
45     unsigned int generic_inl(unsigned long port)
46     {
47     	return *(volatile unsigned long*)PORT2ADDR(port);
48     }
49     
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     
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     
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     
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     
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     
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     
98     void generic_outb(unsigned char b, unsigned long port)
99     {
100     	*(volatile unsigned char*)PORT2ADDR(port) = b;
101     }
102     
103     void generic_outw(unsigned short b, unsigned long port)
104     {
105     	*(volatile unsigned short*)PORT2ADDR(port) = b;
106     }
107     
108     void generic_outl(unsigned int b, unsigned long port)
109     {
110             *(volatile unsigned long*)PORT2ADDR(port) = b;
111     }
112     
113     void generic_outb_p(unsigned char b, unsigned long port)
114     {
115     	*(volatile unsigned char*)PORT2ADDR(port) = b;
116     	delay();
117     }
118     
119     void generic_outw_p(unsigned short b, unsigned long port)
120     {
121     	*(volatile unsigned short*)PORT2ADDR(port) = b;
122     	delay();
123     }
124     
125     void generic_outl_p(unsigned int b, unsigned long port)
126     {
127     	*(volatile unsigned long*)PORT2ADDR(port) = b;
128     	delay();
129     }
130     
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     
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     
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     
155     unsigned char generic_readb(unsigned long addr)
156     {
157     	return *(volatile unsigned char*)addr;
158     }
159     
160     unsigned short generic_readw(unsigned long addr)
161     {
162     	return *(volatile unsigned short*)addr;
163     }
164     
165     unsigned int generic_readl(unsigned long addr)
166     {
167     	return *(volatile unsigned long*)addr;
168     }
169     
170     void generic_writeb(unsigned char b, unsigned long addr)
171     {
172     	*(volatile unsigned char*)addr = b;
173     }
174     
175     void generic_writew(unsigned short b, unsigned long addr)
176     {
177     	*(volatile unsigned short*)addr = b;
178     }
179     
180     void generic_writel(unsigned int b, unsigned long addr)
181     {
182             *(volatile unsigned long*)addr = b;
183     }
184     
185     void * generic_ioremap(unsigned long offset, unsigned long size)
186     {
187     	return (void *) P2SEGADDR(offset);
188     }
189     EXPORT_SYMBOL(generic_ioremap);
190     
191     void generic_iounmap(void *addr)
192     {
193     }
194     EXPORT_SYMBOL(generic_iounmap);
195     
196     unsigned long generic_isa_port2addr(unsigned long offset)
197     {
198     	return offset + generic_io_base;
199     }
200