1
2
3
4#include <linux/pci.h>
5#include <linux/module.h>
6#include <asm/io.h>
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22#ifndef HAVE_ARCH_PIO_SIZE
23
24
25
26
27
28
29
30#define PIO_OFFSET 0x10000UL
31#define PIO_MASK 0x0ffffUL
32#define PIO_RESERVED 0x40000UL
33#endif
34
35
36
37
38#define VERIFY_PIO(port) BUG_ON((port & ~PIO_MASK) != PIO_OFFSET)
39
40#define IO_COND(addr, is_pio, is_mmio) do { \
41 unsigned long port = (unsigned long __force)addr; \
42 if (port < PIO_RESERVED) { \
43 VERIFY_PIO(port); \
44 port &= PIO_MASK; \
45 is_pio; \
46 } else { \
47 is_mmio; \
48 } \
49} while (0)
50
51unsigned int fastcall ioread8(void __iomem *addr)
52{
53 IO_COND(addr, return inb(port), return readb(addr));
54}
55unsigned int fastcall ioread16(void __iomem *addr)
56{
57 IO_COND(addr, return inw(port), return readw(addr));
58}
59unsigned int fastcall ioread32(void __iomem *addr)
60{
61 IO_COND(addr, return inl(port), return readl(addr));
62}
63EXPORT_SYMBOL(ioread8);
64EXPORT_SYMBOL(ioread16);
65EXPORT_SYMBOL(ioread32);
66
67void fastcall iowrite8(u8 val, void __iomem *addr)
68{
69 IO_COND(addr, outb(val,port), writeb(val, addr));
70}
71void fastcall iowrite16(u16 val, void __iomem *addr)
72{
73 IO_COND(addr, outw(val,port), writew(val, addr));
74}
75void fastcall iowrite32(u32 val, void __iomem *addr)
76{
77 IO_COND(addr, outl(val,port), writel(val, addr));
78}
79EXPORT_SYMBOL(iowrite8);
80EXPORT_SYMBOL(iowrite16);
81EXPORT_SYMBOL(iowrite32);
82
83
84
85
86
87
88
89static inline void mmio_insb(void __iomem *addr, u8 *dst, int count)
90{
91 while (--count >= 0) {
92 u8 data = __raw_readb(addr);
93 *dst = data;
94 dst++;
95 }
96}
97static inline void mmio_insw(void __iomem *addr, u16 *dst, int count)
98{
99 while (--count >= 0) {
100 u16 data = __raw_readw(addr);
101 *dst = data;
102 dst++;
103 }
104}
105static inline void mmio_insl(void __iomem *addr, u32 *dst, int count)
106{
107 while (--count >= 0) {
108 u32 data = __raw_readl(addr);
109 *dst = data;
110 dst++;
111 }
112}
113
114static inline void mmio_outsb(void __iomem *addr, const u8 *src, int count)
115{
116 while (--count >= 0) {
117 __raw_writeb(*src, addr);
118 src++;
119 }
120}
121static inline void mmio_outsw(void __iomem *addr, const u16 *src, int count)
122{
123 while (--count >= 0) {
124 __raw_writew(*src, addr);
125 src++;
126 }
127}
128static inline void mmio_outsl(void __iomem *addr, const u32 *src, int count)
129{
130 while (--count >= 0) {
131 __raw_writel(*src, addr);
132 src++;
133 }
134}
135
136void fastcall ioread8_rep(void __iomem *addr, void *dst, unsigned long count)
137{
138 IO_COND(addr, insb(port,dst,count), mmio_insb(addr, dst, count));
139}
140void fastcall ioread16_rep(void __iomem *addr, void *dst, unsigned long count)
141{
142 IO_COND(addr, insw(port,dst,count), mmio_insw(addr, dst, count));
143}
144void fastcall ioread32_rep(void __iomem *addr, void *dst, unsigned long count)
145{
146 IO_COND(addr, insl(port,dst,count), mmio_insl(addr, dst, count));
147}
148EXPORT_SYMBOL(ioread8_rep);
149EXPORT_SYMBOL(ioread16_rep);
150EXPORT_SYMBOL(ioread32_rep);
151
152void fastcall iowrite8_rep(void __iomem *addr, const void *src, unsigned long count)
153{
154 IO_COND(addr, outsb(port, src, count), mmio_outsb(addr, src, count));
155}
156void fastcall iowrite16_rep(void __iomem *addr, const void *src, unsigned long count)
157{
158 IO_COND(addr, outsw(port, src, count), mmio_outsw(addr, src, count));
159}
160void fastcall iowrite32_rep(void __iomem *addr, const void *src, unsigned long count)
161{
162 IO_COND(addr, outsl(port, src,count), mmio_outsl(addr, src, count));
163}
164EXPORT_SYMBOL(iowrite8_rep);
165EXPORT_SYMBOL(iowrite16_rep);
166EXPORT_SYMBOL(iowrite32_rep);
167
168
169void __iomem *ioport_map(unsigned long port, unsigned int nr)
170{
171 if (port > PIO_MASK)
172 return NULL;
173 return (void __iomem *) (unsigned long) (port + PIO_OFFSET);
174}
175
176void ioport_unmap(void __iomem *addr)
177{
178
179}
180EXPORT_SYMBOL(ioport_map);
181EXPORT_SYMBOL(ioport_unmap);
182
183
184void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen)
185{
186 unsigned long start = pci_resource_start(dev, bar);
187 unsigned long len = pci_resource_len(dev, bar);
188 unsigned long flags = pci_resource_flags(dev, bar);
189
190 if (!len || !start)
191 return NULL;
192 if (maxlen && len > maxlen)
193 len = maxlen;
194 if (flags & IORESOURCE_IO)
195 return ioport_map(start, len);
196 if (flags & IORESOURCE_MEM) {
197 if (flags & IORESOURCE_CACHEABLE)
198 return ioremap(start, len);
199 return ioremap_nocache(start, len);
200 }
201
202 return NULL;
203}
204
205void pci_iounmap(struct pci_dev *dev, void __iomem * addr)
206{
207 IO_COND(addr, , iounmap(addr));
208}
209EXPORT_SYMBOL(pci_iomap);
210EXPORT_SYMBOL(pci_iounmap);
211