blob: d51d5cb0a4a937db84f5952afac2ea264b64faaf [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
Ralf Baechle140c1722006-12-07 15:35:43 +01002 * Implement the default iomap interfaces
Linus Torvalds1da177e2005-04-16 15:20:36 -07003 *
Ralf Baechle140c1722006-12-07 15:35:43 +01004 * (C) Copyright 2004 Linus Torvalds
5 * (C) Copyright 2006 Ralf Baechle <ralf@linux-mips.org>
6 * (C) Copyright 2007 MIPS Technologies, Inc.
7 * written by Ralf Baechle <ralf@linux-mips.org>
Linus Torvalds1da177e2005-04-16 15:20:36 -07008 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07009#include <linux/pci.h>
Ralf Baechle140c1722006-12-07 15:35:43 +010010#include <linux/module.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070011#include <asm/io.h>
12
Ralf Baechle140c1722006-12-07 15:35:43 +010013/*
14 * Read/write from/to an (offsettable) iomem cookie. It might be a PIO
15 * access or a MMIO access, these functions don't care. The info is
16 * encoded in the hardware mapping set up by the mapping functions
17 * (or the cookie itself, depending on implementation and hw).
18 *
19 * The generic routines don't assume any hardware mappings, and just
20 * encode the PIO/MMIO as part of the cookie. They coldly assume that
21 * the MMIO IO mappings are not in the low address range.
22 *
23 * Architectures for which this is not true can't use this generic
24 * implementation and should do their own copy.
25 */
26
27#define PIO_MASK 0x0ffffUL
28
29unsigned int ioread8(void __iomem *addr)
30{
31 return readb(addr);
32}
33
34EXPORT_SYMBOL(ioread8);
35
36unsigned int ioread16(void __iomem *addr)
37{
38 return readw(addr);
39}
40
41EXPORT_SYMBOL(ioread16);
42
43unsigned int ioread16be(void __iomem *addr)
44{
45 return be16_to_cpu(__raw_readw(addr));
46}
47
48EXPORT_SYMBOL(ioread16be);
49
50unsigned int ioread32(void __iomem *addr)
51{
52 return readl(addr);
53}
54
55EXPORT_SYMBOL(ioread32);
56
57unsigned int ioread32be(void __iomem *addr)
58{
59 return be32_to_cpu(__raw_readl(addr));
60}
61
62EXPORT_SYMBOL(ioread32be);
63
64void iowrite8(u8 val, void __iomem *addr)
65{
66 writeb(val, addr);
67}
68
69EXPORT_SYMBOL(iowrite8);
70
71void iowrite16(u16 val, void __iomem *addr)
72{
73 writew(val, addr);
74}
75
76EXPORT_SYMBOL(iowrite16);
77
78void iowrite16be(u16 val, void __iomem *addr)
79{
80 __raw_writew(cpu_to_be16(val), addr);
81}
82
83EXPORT_SYMBOL(iowrite16be);
84
85void iowrite32(u32 val, void __iomem *addr)
86{
87 writel(val, addr);
88}
89
90EXPORT_SYMBOL(iowrite32);
91
92void iowrite32be(u32 val, void __iomem *addr)
93{
94 __raw_writel(cpu_to_be32(val), addr);
95}
96
97EXPORT_SYMBOL(iowrite32be);
98
99/*
100 * These are the "repeat MMIO read/write" functions.
101 * Note the "__raw" accesses, since we don't want to
102 * convert to CPU byte order. We write in "IO byte
103 * order" (we also don't have IO barriers).
104 */
105static inline void mmio_insb(void __iomem *addr, u8 *dst, int count)
106{
107 while (--count >= 0) {
108 u8 data = __raw_readb(addr);
109 *dst = data;
110 dst++;
111 }
112}
113
114static inline void mmio_insw(void __iomem *addr, u16 *dst, int count)
115{
116 while (--count >= 0) {
117 u16 data = __raw_readw(addr);
118 *dst = data;
119 dst++;
120 }
121}
122
123static inline void mmio_insl(void __iomem *addr, u32 *dst, int count)
124{
125 while (--count >= 0) {
126 u32 data = __raw_readl(addr);
127 *dst = data;
128 dst++;
129 }
130}
131
132static inline void mmio_outsb(void __iomem *addr, const u8 *src, int count)
133{
134 while (--count >= 0) {
135 __raw_writeb(*src, addr);
136 src++;
137 }
138}
139
140static inline void mmio_outsw(void __iomem *addr, const u16 *src, int count)
141{
142 while (--count >= 0) {
143 __raw_writew(*src, addr);
144 src++;
145 }
146}
147
148static inline void mmio_outsl(void __iomem *addr, const u32 *src, int count)
149{
150 while (--count >= 0) {
151 __raw_writel(*src, addr);
152 src++;
153 }
154}
155
156void ioread8_rep(void __iomem *addr, void *dst, unsigned long count)
157{
158 mmio_insb(addr, dst, count);
159}
160
161EXPORT_SYMBOL(ioread8_rep);
162
163void ioread16_rep(void __iomem *addr, void *dst, unsigned long count)
164{
165 mmio_insw(addr, dst, count);
166}
167
168EXPORT_SYMBOL(ioread16_rep);
169
170void ioread32_rep(void __iomem *addr, void *dst, unsigned long count)
171{
172 mmio_insl(addr, dst, count);
173}
174
175EXPORT_SYMBOL(ioread32_rep);
176
177void iowrite8_rep(void __iomem *addr, const void *src, unsigned long count)
178{
179 mmio_outsb(addr, src, count);
180}
181
182EXPORT_SYMBOL(iowrite8_rep);
183
184void iowrite16_rep(void __iomem *addr, const void *src, unsigned long count)
185{
186 mmio_outsw(addr, src, count);
187}
188
189EXPORT_SYMBOL(iowrite16_rep);
190
191void iowrite32_rep(void __iomem *addr, const void *src, unsigned long count)
192{
193 mmio_outsl(addr, src, count);
194}
195
196EXPORT_SYMBOL(iowrite32_rep);
197
198/*
199 * Create a virtual mapping cookie for an IO port range
200 *
201 * This uses the same mapping are as the in/out family which has to be setup
202 * by the platform initialization code.
203 *
204 * Just to make matters somewhat more interesting on MIPS systems with
205 * multiple host bridge each will have it's own ioport address space.
206 */
207static void __iomem *ioport_map_legacy(unsigned long port, unsigned int nr)
208{
209 return (void __iomem *) (mips_io_port_base + port);
210}
211
Linus Torvalds1da177e2005-04-16 15:20:36 -0700212void __iomem *ioport_map(unsigned long port, unsigned int nr)
213{
Ralf Baechle140c1722006-12-07 15:35:43 +0100214 if (port > PIO_MASK)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700215 return NULL;
216
Ralf Baechle140c1722006-12-07 15:35:43 +0100217 return ioport_map_legacy(port, nr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700218}
219
Ralf Baechle140c1722006-12-07 15:35:43 +0100220EXPORT_SYMBOL(ioport_map);
221
Linus Torvalds1da177e2005-04-16 15:20:36 -0700222void ioport_unmap(void __iomem *addr)
223{
Ralf Baechle140c1722006-12-07 15:35:43 +0100224 /* Nothing to do */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700225}
Ralf Baechle140c1722006-12-07 15:35:43 +0100226
Linus Torvalds1da177e2005-04-16 15:20:36 -0700227EXPORT_SYMBOL(ioport_unmap);