1/*
2 * arch/sh/kernel/io_generic.c
3 *
4 * Copyright (C) 2000  Niibe Yutaka
5 * Copyright (C) 2005 - 2007 Paul Mundt
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#include <linux/module.h>
15#include <linux/io.h>
16#include <asm/machvec.h>
17
18#ifdef CONFIG_CPU_SH3
19/* I'm not sure SH7709 has this kind of bug */
20#define dummy_read()	ctrl_inb(0xba000000)
21#else
22#define dummy_read()
23#endif
24
25unsigned long generic_io_base;
26
27static inline void delay(void)
28{
29	ctrl_inw(0xa0000000);
30}
31
32u8 generic_inb(unsigned long port)
33{
34	return ctrl_inb((unsigned long __force)ioport_map(port, 1));
35}
36
37u16 generic_inw(unsigned long port)
38{
39	return ctrl_inw((unsigned long __force)ioport_map(port, 2));
40}
41
42u32 generic_inl(unsigned long port)
43{
44	return ctrl_inl((unsigned long __force)ioport_map(port, 4));
45}
46
47u8 generic_inb_p(unsigned long port)
48{
49	unsigned long v = generic_inb(port);
50
51	delay();
52	return v;
53}
54
55u16 generic_inw_p(unsigned long port)
56{
57	unsigned long v = generic_inw(port);
58
59	delay();
60	return v;
61}
62
63u32 generic_inl_p(unsigned long port)
64{
65	unsigned long v = generic_inl(port);
66
67	delay();
68	return v;
69}
70
71/*
72 * insb/w/l all read a series of bytes/words/longs from a fixed port
73 * address. However as the port address doesn't change we only need to
74 * convert the port address to real address once.
75 */
76
77void generic_insb(unsigned long port, void *dst, unsigned long count)
78{
79	volatile u8 *port_addr;
80	u8 *buf = dst;
81
82	port_addr = (volatile u8 *)ioport_map(port, 1);
83	while (count--)
84		*buf++ = *port_addr;
85}
86
87void generic_insw(unsigned long port, void *dst, unsigned long count)
88{
89	volatile u16 *port_addr;
90	u16 *buf = dst;
91
92	port_addr = (volatile u16 *)ioport_map(port, 2);
93	while (count--)
94		*buf++ = *port_addr;
95
96	dummy_read();
97}
98
99void generic_insl(unsigned long port, void *dst, unsigned long count)
100{
101	volatile u32 *port_addr;
102	u32 *buf = dst;
103
104	port_addr = (volatile u32 *)ioport_map(port, 4);
105	while (count--)
106		*buf++ = *port_addr;
107
108	dummy_read();
109}
110
111void generic_outb(u8 b, unsigned long port)
112{
113	ctrl_outb(b, (unsigned long __force)ioport_map(port, 1));
114}
115
116void generic_outw(u16 b, unsigned long port)
117{
118	ctrl_outw(b, (unsigned long __force)ioport_map(port, 2));
119}
120
121void generic_outl(u32 b, unsigned long port)
122{
123	ctrl_outl(b, (unsigned long __force)ioport_map(port, 4));
124}
125
126void generic_outb_p(u8 b, unsigned long port)
127{
128	generic_outb(b, port);
129	delay();
130}
131
132void generic_outw_p(u16 b, unsigned long port)
133{
134	generic_outw(b, port);
135	delay();
136}
137
138void generic_outl_p(u32 b, unsigned long port)
139{
140	generic_outl(b, port);
141	delay();
142}
143
144/*
145 * outsb/w/l all write a series of bytes/words/longs to a fixed port
146 * address. However as the port address doesn't change we only need to
147 * convert the port address to real address once.
148 */
149void generic_outsb(unsigned long port, const void *src, unsigned long count)
150{
151	volatile u8 *port_addr;
152	const u8 *buf = src;
153
154	port_addr = (volatile u8 __force *)ioport_map(port, 1);
155
156	while (count--)
157		*port_addr = *buf++;
158}
159
160void generic_outsw(unsigned long port, const void *src, unsigned long count)
161{
162	volatile u16 *port_addr;
163	const u16 *buf = src;
164
165	port_addr = (volatile u16 __force *)ioport_map(port, 2);
166
167	while (count--)
168		*port_addr = *buf++;
169
170	dummy_read();
171}
172
173void generic_outsl(unsigned long port, const void *src, unsigned long count)
174{
175	volatile u32 *port_addr;
176	const u32 *buf = src;
177
178	port_addr = (volatile u32 __force *)ioport_map(port, 4);
179	while (count--)
180		*port_addr = *buf++;
181
182	dummy_read();
183}
184
185u8 generic_readb(void __iomem *addr)
186{
187	return ctrl_inb((unsigned long __force)addr);
188}
189
190u16 generic_readw(void __iomem *addr)
191{
192	return ctrl_inw((unsigned long __force)addr);
193}
194
195u32 generic_readl(void __iomem *addr)
196{
197	return ctrl_inl((unsigned long __force)addr);
198}
199
200void generic_writeb(u8 b, void __iomem *addr)
201{
202	ctrl_outb(b, (unsigned long __force)addr);
203}
204
205void generic_writew(u16 b, void __iomem *addr)
206{
207	ctrl_outw(b, (unsigned long __force)addr);
208}
209
210void generic_writel(u32 b, void __iomem *addr)
211{
212	ctrl_outl(b, (unsigned long __force)addr);
213}
214
215void __iomem *generic_ioport_map(unsigned long addr, unsigned int size)
216{
217	return (void __iomem *)(addr + generic_io_base);
218}
219
220void generic_ioport_unmap(void __iomem *addr)
221{
222}
223