io_generic.c 4.4 KB
Newer Older
P
Paul Mundt 已提交
1 2
/*
 * arch/sh/kernel/io_generic.c
L
Linus Torvalds 已提交
3 4
 *
 * Copyright (C) 2000  Niibe Yutaka
P
Paul Mundt 已提交
5
 * Copyright (C) 2005 - 2007 Paul Mundt
L
Linus Torvalds 已提交
6 7 8 9 10 11 12 13
 *
 * Generic I/O routine. These can be used where a machine specific version
 * is not required.
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 */
14
#include <linux/module.h>
P
Paul Mundt 已提交
15
#include <linux/io.h>
L
Linus Torvalds 已提交
16 17
#include <asm/machvec.h>

18 19 20
#ifdef CONFIG_CPU_SH3
/* SH3 has a PCMCIA bug that needs a dummy read from area 6 for a
 * workaround. */
L
Linus Torvalds 已提交
21
/* I'm not sure SH7709 has this kind of bug */
22 23 24
#define dummy_read()	ctrl_inb(0xba000000)
#else
#define dummy_read()
L
Linus Torvalds 已提交
25 26 27 28 29 30 31 32 33
#endif

unsigned long generic_io_base;

static inline void delay(void)
{
	ctrl_inw(0xa0000000);
}

34
u8 generic_inb(unsigned long port)
L
Linus Torvalds 已提交
35
{
M
Magnus Damm 已提交
36
	return ctrl_inb((unsigned long __force)__ioport_map(port, 1));
L
Linus Torvalds 已提交
37 38
}

39
u16 generic_inw(unsigned long port)
L
Linus Torvalds 已提交
40
{
M
Magnus Damm 已提交
41
	return ctrl_inw((unsigned long __force)__ioport_map(port, 2));
L
Linus Torvalds 已提交
42 43
}

44
u32 generic_inl(unsigned long port)
L
Linus Torvalds 已提交
45
{
M
Magnus Damm 已提交
46
	return ctrl_inl((unsigned long __force)__ioport_map(port, 4));
L
Linus Torvalds 已提交
47 48
}

49
u8 generic_inb_p(unsigned long port)
L
Linus Torvalds 已提交
50
{
51
	unsigned long v = generic_inb(port);
L
Linus Torvalds 已提交
52 53 54 55 56

	delay();
	return v;
}

57
u16 generic_inw_p(unsigned long port)
L
Linus Torvalds 已提交
58
{
59
	unsigned long v = generic_inw(port);
L
Linus Torvalds 已提交
60 61 62 63 64

	delay();
	return v;
}

65
u32 generic_inl_p(unsigned long port)
L
Linus Torvalds 已提交
66
{
67
	unsigned long v = generic_inl(port);
L
Linus Torvalds 已提交
68 69 70 71 72 73 74 75 76 77 78

	delay();
	return v;
}

/*
 * insb/w/l all read a series of bytes/words/longs from a fixed port
 * address. However as the port address doesn't change we only need to
 * convert the port address to real address once.
 */

79
void generic_insb(unsigned long port, void *dst, unsigned long count)
L
Linus Torvalds 已提交
80
{
81 82
	volatile u8 *port_addr;
	u8 *buf = dst;
L
Linus Torvalds 已提交
83

P
Paul Mundt 已提交
84
	port_addr = (volatile u8 __force *)__ioport_map(port, 1);
85 86
	while (count--)
		*buf++ = *port_addr;
L
Linus Torvalds 已提交
87 88
}

89
void generic_insw(unsigned long port, void *dst, unsigned long count)
L
Linus Torvalds 已提交
90
{
91 92
	volatile u16 *port_addr;
	u16 *buf = dst;
L
Linus Torvalds 已提交
93

P
Paul Mundt 已提交
94
	port_addr = (volatile u16 __force *)__ioport_map(port, 2);
95 96
	while (count--)
		*buf++ = *port_addr;
L
Linus Torvalds 已提交
97

98
	dummy_read();
L
Linus Torvalds 已提交
99 100
}

101
void generic_insl(unsigned long port, void *dst, unsigned long count)
L
Linus Torvalds 已提交
102
{
103 104
	volatile u32 *port_addr;
	u32 *buf = dst;
L
Linus Torvalds 已提交
105

P
Paul Mundt 已提交
106
	port_addr = (volatile u32 __force *)__ioport_map(port, 4);
107 108
	while (count--)
		*buf++ = *port_addr;
L
Linus Torvalds 已提交
109

110
	dummy_read();
L
Linus Torvalds 已提交
111 112
}

113
void generic_outb(u8 b, unsigned long port)
L
Linus Torvalds 已提交
114
{
M
Magnus Damm 已提交
115
	ctrl_outb(b, (unsigned long __force)__ioport_map(port, 1));
L
Linus Torvalds 已提交
116 117
}

118
void generic_outw(u16 b, unsigned long port)
L
Linus Torvalds 已提交
119
{
M
Magnus Damm 已提交
120
	ctrl_outw(b, (unsigned long __force)__ioport_map(port, 2));
L
Linus Torvalds 已提交
121 122
}

123
void generic_outl(u32 b, unsigned long port)
L
Linus Torvalds 已提交
124
{
M
Magnus Damm 已提交
125
	ctrl_outl(b, (unsigned long __force)__ioport_map(port, 4));
L
Linus Torvalds 已提交
126 127
}

128
void generic_outb_p(u8 b, unsigned long port)
L
Linus Torvalds 已提交
129
{
130
	generic_outb(b, port);
L
Linus Torvalds 已提交
131 132 133
	delay();
}

134
void generic_outw_p(u16 b, unsigned long port)
L
Linus Torvalds 已提交
135
{
136
	generic_outw(b, port);
L
Linus Torvalds 已提交
137 138 139
	delay();
}

140
void generic_outl_p(u32 b, unsigned long port)
L
Linus Torvalds 已提交
141
{
142
	generic_outl(b, port);
L
Linus Torvalds 已提交
143 144 145 146 147 148 149 150
	delay();
}

/*
 * outsb/w/l all write a series of bytes/words/longs to a fixed port
 * address. However as the port address doesn't change we only need to
 * convert the port address to real address once.
 */
151
void generic_outsb(unsigned long port, const void *src, unsigned long count)
L
Linus Torvalds 已提交
152
{
153 154
	volatile u8 *port_addr;
	const u8 *buf = src;
L
Linus Torvalds 已提交
155

M
Magnus Damm 已提交
156
	port_addr = (volatile u8 __force *)__ioport_map(port, 1);
L
Linus Torvalds 已提交
157

158 159
	while (count--)
		*port_addr = *buf++;
L
Linus Torvalds 已提交
160 161
}

162
void generic_outsw(unsigned long port, const void *src, unsigned long count)
L
Linus Torvalds 已提交
163
{
164 165
	volatile u16 *port_addr;
	const u16 *buf = src;
L
Linus Torvalds 已提交
166

M
Magnus Damm 已提交
167
	port_addr = (volatile u16 __force *)__ioport_map(port, 2);
L
Linus Torvalds 已提交
168

169 170
	while (count--)
		*port_addr = *buf++;
L
Linus Torvalds 已提交
171

172
	dummy_read();
L
Linus Torvalds 已提交
173 174
}

175
void generic_outsl(unsigned long port, const void *src, unsigned long count)
L
Linus Torvalds 已提交
176
{
177 178
	volatile u32 *port_addr;
	const u32 *buf = src;
L
Linus Torvalds 已提交
179

M
Magnus Damm 已提交
180
	port_addr = (volatile u32 __force *)__ioport_map(port, 4);
181 182
	while (count--)
		*port_addr = *buf++;
L
Linus Torvalds 已提交
183

184
	dummy_read();
L
Linus Torvalds 已提交
185 186
}

187
u8 generic_readb(void __iomem *addr)
L
Linus Torvalds 已提交
188
{
189
	return ctrl_inb((unsigned long __force)addr);
L
Linus Torvalds 已提交
190 191
}

192
u16 generic_readw(void __iomem *addr)
L
Linus Torvalds 已提交
193
{
194
	return ctrl_inw((unsigned long __force)addr);
L
Linus Torvalds 已提交
195 196
}

197
u32 generic_readl(void __iomem *addr)
L
Linus Torvalds 已提交
198
{
199
	return ctrl_inl((unsigned long __force)addr);
L
Linus Torvalds 已提交
200 201
}

202
void generic_writeb(u8 b, void __iomem *addr)
L
Linus Torvalds 已提交
203
{
204
	ctrl_outb(b, (unsigned long __force)addr);
L
Linus Torvalds 已提交
205 206
}

207
void generic_writew(u16 b, void __iomem *addr)
L
Linus Torvalds 已提交
208
{
209
	ctrl_outw(b, (unsigned long __force)addr);
L
Linus Torvalds 已提交
210 211
}

212
void generic_writel(u32 b, void __iomem *addr)
L
Linus Torvalds 已提交
213
{
214
	ctrl_outl(b, (unsigned long __force)addr);
L
Linus Torvalds 已提交
215 216
}

217
void __iomem *generic_ioport_map(unsigned long addr, unsigned int size)
L
Linus Torvalds 已提交
218
{
219
	return (void __iomem *)(addr + generic_io_base);
L
Linus Torvalds 已提交
220 221
}

222
void generic_ioport_unmap(void __iomem *addr)
L
Linus Torvalds 已提交
223 224
{
}