io_generic.c 3.7 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 */
P
Paul Mundt 已提交
22
#define dummy_read()	__raw_readb(0xba000000)
23 24
#else
#define dummy_read()
L
Linus Torvalds 已提交
25 26 27 28
#endif

unsigned long generic_io_base;

29
u8 generic_inb(unsigned long port)
L
Linus Torvalds 已提交
30
{
P
Paul Mundt 已提交
31
	return __raw_readb(__ioport_map(port, 1));
L
Linus Torvalds 已提交
32 33
}

34
u16 generic_inw(unsigned long port)
L
Linus Torvalds 已提交
35
{
P
Paul Mundt 已提交
36
	return __raw_readw(__ioport_map(port, 2));
L
Linus Torvalds 已提交
37 38
}

39
u32 generic_inl(unsigned long port)
L
Linus Torvalds 已提交
40
{
P
Paul Mundt 已提交
41
	return __raw_readl(__ioport_map(port, 4));
L
Linus Torvalds 已提交
42 43
}

44
u8 generic_inb_p(unsigned long port)
L
Linus Torvalds 已提交
45
{
46
	unsigned long v = generic_inb(port);
L
Linus Torvalds 已提交
47

P
Paul Mundt 已提交
48
	ctrl_delay();
L
Linus Torvalds 已提交
49 50 51
	return v;
}

52
u16 generic_inw_p(unsigned long port)
L
Linus Torvalds 已提交
53
{
54
	unsigned long v = generic_inw(port);
L
Linus Torvalds 已提交
55

P
Paul Mundt 已提交
56
	ctrl_delay();
L
Linus Torvalds 已提交
57 58 59
	return v;
}

60
u32 generic_inl_p(unsigned long port)
L
Linus Torvalds 已提交
61
{
62
	unsigned long v = generic_inl(port);
L
Linus Torvalds 已提交
63

P
Paul Mundt 已提交
64
	ctrl_delay();
L
Linus Torvalds 已提交
65 66 67 68 69 70 71 72 73
	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.
 */

74
void generic_insb(unsigned long port, void *dst, unsigned long count)
L
Linus Torvalds 已提交
75
{
76 77
	volatile u8 *port_addr;
	u8 *buf = dst;
L
Linus Torvalds 已提交
78

P
Paul Mundt 已提交
79
	port_addr = (volatile u8 __force *)__ioport_map(port, 1);
80 81
	while (count--)
		*buf++ = *port_addr;
L
Linus Torvalds 已提交
82 83
}

84
void generic_insw(unsigned long port, void *dst, unsigned long count)
L
Linus Torvalds 已提交
85
{
86 87
	volatile u16 *port_addr;
	u16 *buf = dst;
L
Linus Torvalds 已提交
88

P
Paul Mundt 已提交
89
	port_addr = (volatile u16 __force *)__ioport_map(port, 2);
90 91
	while (count--)
		*buf++ = *port_addr;
L
Linus Torvalds 已提交
92

93
	dummy_read();
L
Linus Torvalds 已提交
94 95
}

96
void generic_insl(unsigned long port, void *dst, unsigned long count)
L
Linus Torvalds 已提交
97
{
98 99
	volatile u32 *port_addr;
	u32 *buf = dst;
L
Linus Torvalds 已提交
100

P
Paul Mundt 已提交
101
	port_addr = (volatile u32 __force *)__ioport_map(port, 4);
102 103
	while (count--)
		*buf++ = *port_addr;
L
Linus Torvalds 已提交
104

105
	dummy_read();
L
Linus Torvalds 已提交
106 107
}

108
void generic_outb(u8 b, unsigned long port)
L
Linus Torvalds 已提交
109
{
P
Paul Mundt 已提交
110
	__raw_writeb(b, __ioport_map(port, 1));
L
Linus Torvalds 已提交
111 112
}

113
void generic_outw(u16 b, unsigned long port)
L
Linus Torvalds 已提交
114
{
P
Paul Mundt 已提交
115
	__raw_writew(b, __ioport_map(port, 2));
L
Linus Torvalds 已提交
116 117
}

118
void generic_outl(u32 b, unsigned long port)
L
Linus Torvalds 已提交
119
{
P
Paul Mundt 已提交
120
	__raw_writel(b, __ioport_map(port, 4));
L
Linus Torvalds 已提交
121 122
}

123
void generic_outb_p(u8 b, unsigned long port)
L
Linus Torvalds 已提交
124
{
125
	generic_outb(b, port);
P
Paul Mundt 已提交
126
	ctrl_delay();
L
Linus Torvalds 已提交
127 128
}

129
void generic_outw_p(u16 b, unsigned long port)
L
Linus Torvalds 已提交
130
{
131
	generic_outw(b, port);
P
Paul Mundt 已提交
132
	ctrl_delay();
L
Linus Torvalds 已提交
133 134
}

135
void generic_outl_p(u32 b, unsigned long port)
L
Linus Torvalds 已提交
136
{
137
	generic_outl(b, port);
P
Paul Mundt 已提交
138
	ctrl_delay();
L
Linus Torvalds 已提交
139 140 141 142 143 144 145
}

/*
 * 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.
 */
146
void generic_outsb(unsigned long port, const void *src, unsigned long count)
L
Linus Torvalds 已提交
147
{
148 149
	volatile u8 *port_addr;
	const u8 *buf = src;
L
Linus Torvalds 已提交
150

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

153 154
	while (count--)
		*port_addr = *buf++;
L
Linus Torvalds 已提交
155 156
}

157
void generic_outsw(unsigned long port, const void *src, unsigned long count)
L
Linus Torvalds 已提交
158
{
159 160
	volatile u16 *port_addr;
	const u16 *buf = src;
L
Linus Torvalds 已提交
161

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

164 165
	while (count--)
		*port_addr = *buf++;
L
Linus Torvalds 已提交
166

167
	dummy_read();
L
Linus Torvalds 已提交
168 169
}

170
void generic_outsl(unsigned long port, const void *src, unsigned long count)
L
Linus Torvalds 已提交
171
{
172 173
	volatile u32 *port_addr;
	const u32 *buf = src;
L
Linus Torvalds 已提交
174

M
Magnus Damm 已提交
175
	port_addr = (volatile u32 __force *)__ioport_map(port, 4);
176 177
	while (count--)
		*port_addr = *buf++;
L
Linus Torvalds 已提交
178

179
	dummy_read();
L
Linus Torvalds 已提交
180 181
}

182
void __iomem *generic_ioport_map(unsigned long addr, unsigned int size)
L
Linus Torvalds 已提交
183
{
184
	return (void __iomem *)(addr + generic_io_base);
L
Linus Torvalds 已提交
185 186
}

187
void generic_ioport_unmap(void __iomem *addr)
L
Linus Torvalds 已提交
188 189
{
}