1#ifndef _ASM_IO_H
2#define _ASM_IO_H
3
4#include <linux/config.h>
5#include <linux/string.h>
6#include <linux/compiler.h>
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41#define IO_SPACE_LIMIT 0xffff
42
43#define XQUAD_PORTIO_BASE 0xfe400000
44#define XQUAD_PORTIO_QUAD 0x40000
45
46#ifdef __KERNEL__
47
48#include <asm-generic/iomap.h>
49
50#include <linux/vmalloc.h>
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65static inline unsigned long virt_to_phys(volatile void * address)
66{
67 return __pa(address);
68}
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83static inline void * phys_to_virt(unsigned long address)
84{
85 return __va(address);
86}
87
88
89
90
91#define page_to_phys(page) ((dma_addr_t)page_to_pfn(page) << PAGE_SHIFT)
92
93extern void __iomem * __ioremap(unsigned long offset, unsigned long size, unsigned long flags);
94
95
96
97
98
99
100
101
102
103
104
105
106
107static inline void __iomem * ioremap(unsigned long offset, unsigned long size)
108{
109 return __ioremap(offset, size, 0);
110}
111
112extern void __iomem * ioremap_nocache(unsigned long offset, unsigned long size);
113extern void iounmap(volatile void __iomem *addr);
114
115
116
117
118
119
120extern void *bt_ioremap(unsigned long offset, unsigned long size);
121extern void bt_iounmap(void *addr, unsigned long size);
122
123
124
125
126#define isa_virt_to_bus virt_to_phys
127#define isa_page_to_bus page_to_phys
128#define isa_bus_to_virt phys_to_virt
129
130
131
132
133
134
135
136#define virt_to_bus virt_to_phys
137#define bus_to_virt phys_to_virt
138
139
140
141
142
143
144
145
146static inline unsigned char readb(const volatile void __iomem *addr)
147{
148 return *(volatile unsigned char __force *) addr;
149}
150static inline unsigned short readw(const volatile void __iomem *addr)
151{
152 return *(volatile unsigned short __force *) addr;
153}
154static inline unsigned int readl(const volatile void __iomem *addr)
155{
156 return *(volatile unsigned int __force *) addr;
157}
158#define readb_relaxed(addr) readb(addr)
159#define readw_relaxed(addr) readw(addr)
160#define readl_relaxed(addr) readl(addr)
161#define __raw_readb readb
162#define __raw_readw readw
163#define __raw_readl readl
164
165static inline void writeb(unsigned char b, volatile void __iomem *addr)
166{
167 *(volatile unsigned char __force *) addr = b;
168}
169static inline void writew(unsigned short b, volatile void __iomem *addr)
170{
171 *(volatile unsigned short __force *) addr = b;
172}
173static inline void writel(unsigned int b, volatile void __iomem *addr)
174{
175 *(volatile unsigned int __force *) addr = b;
176}
177#define __raw_writeb writeb
178#define __raw_writew writew
179#define __raw_writel writel
180
181#define mmiowb()
182
183static inline void memset_io(volatile void __iomem *addr, unsigned char val, int count)
184{
185 memset((void __force *) addr, val, count);
186}
187static inline void memcpy_fromio(void *dst, const volatile void __iomem *src, int count)
188{
189 __memcpy(dst, (void __force *) src, count);
190}
191static inline void memcpy_toio(volatile void __iomem *dst, const void *src, int count)
192{
193 __memcpy((void __force *) dst, src, count);
194}
195
196
197
198
199
200
201
202
203
204#define __ISA_IO_base ((char __iomem *)(PAGE_OFFSET))
205
206#define isa_readb(a) readb(__ISA_IO_base + (a))
207#define isa_readw(a) readw(__ISA_IO_base + (a))
208#define isa_readl(a) readl(__ISA_IO_base + (a))
209#define isa_writeb(b,a) writeb(b,__ISA_IO_base + (a))
210#define isa_writew(w,a) writew(w,__ISA_IO_base + (a))
211#define isa_writel(l,a) writel(l,__ISA_IO_base + (a))
212#define isa_memset_io(a,b,c) memset_io(__ISA_IO_base + (a),(b),(c))
213#define isa_memcpy_fromio(a,b,c) memcpy_fromio((a),__ISA_IO_base + (b),(c))
214#define isa_memcpy_toio(a,b,c) memcpy_toio(__ISA_IO_base + (a),(b),(c))
215
216
217
218
219
220
221#define eth_io_copy_and_sum(a,b,c,d) eth_copy_and_sum((a),(void __force *)(b),(c),(d))
222#define isa_eth_io_copy_and_sum(a,b,c,d) eth_copy_and_sum((a),(void __force *)(__ISA_IO_base + (b)),(c),(d))
223
224
225
226
227
228
229
230
231
232
233
234
235static inline int check_signature(volatile void __iomem * io_addr,
236 const unsigned char *signature, int length)
237{
238 int retval = 0;
239 do {
240 if (readb(io_addr) != *signature)
241 goto out;
242 io_addr++;
243 signature++;
244 length--;
245 } while (length);
246 retval = 1;
247out:
248 return retval;
249}
250
251
252
253
254
255
256
257
258
259#if defined(CONFIG_X86_OOSTORE) || defined(CONFIG_X86_PPRO_FENCE)
260
261static inline void flush_write_buffers(void)
262{
263 __asm__ __volatile__ ("lock; addl $0,0(%%esp)": : :"memory");
264}
265
266#define dma_cache_inv(_start,_size) flush_write_buffers()
267#define dma_cache_wback(_start,_size) flush_write_buffers()
268#define dma_cache_wback_inv(_start,_size) flush_write_buffers()
269
270#else
271
272
273
274#define dma_cache_inv(_start,_size) do { } while (0)
275#define dma_cache_wback(_start,_size) do { } while (0)
276#define dma_cache_wback_inv(_start,_size) do { } while (0)
277#define flush_write_buffers()
278
279#endif
280
281#endif
282
283#ifdef SLOW_IO_BY_JUMPING
284#define __SLOW_DOWN_IO "jmp 1f; 1: jmp 1f; 1:"
285#else
286#define __SLOW_DOWN_IO "outb %%al,$0x80;"
287#endif
288
289static inline void slow_down_io(void) {
290 __asm__ __volatile__(
291 __SLOW_DOWN_IO
292#ifdef REALLY_SLOW_IO
293 __SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO
294#endif
295 : : );
296}
297
298#ifdef CONFIG_X86_NUMAQ
299extern void *xquad_portio;
300#define XQUAD_PORT_ADDR(port, quad) (xquad_portio + (XQUAD_PORTIO_QUAD*quad) + port)
301#define __BUILDIO(bwl,bw,type) \
302static inline void out##bwl##_quad(unsigned type value, int port, int quad) { \
303 if (xquad_portio) \
304 write##bwl(value, XQUAD_PORT_ADDR(port, quad)); \
305 else \
306 out##bwl##_local(value, port); \
307} \
308static inline void out##bwl(unsigned type value, int port) { \
309 out##bwl##_quad(value, port, 0); \
310} \
311static inline unsigned type in##bwl##_quad(int port, int quad) { \
312 if (xquad_portio) \
313 return read##bwl(XQUAD_PORT_ADDR(port, quad)); \
314 else \
315 return in##bwl##_local(port); \
316} \
317static inline unsigned type in##bwl(int port) { \
318 return in##bwl##_quad(port, 0); \
319}
320#else
321#define __BUILDIO(bwl,bw,type) \
322static inline void out##bwl(unsigned type value, int port) { \
323 out##bwl##_local(value, port); \
324} \
325static inline unsigned type in##bwl(int port) { \
326 return in##bwl##_local(port); \
327}
328#endif
329
330
331#define BUILDIO(bwl,bw,type) \
332static inline void out##bwl##_local(unsigned type value, int port) { \
333 __asm__ __volatile__("out" #bwl " %" #bw "0, %w1" : : "a"(value), "Nd"(port)); \
334} \
335static inline unsigned type in##bwl##_local(int port) { \
336 unsigned type value; \
337 __asm__ __volatile__("in" #bwl " %w1, %" #bw "0" : "=a"(value) : "Nd"(port)); \
338 return value; \
339} \
340static inline void out##bwl##_local_p(unsigned type value, int port) { \
341 out##bwl##_local(value, port); \
342 slow_down_io(); \
343} \
344static inline unsigned type in##bwl##_local_p(int port) { \
345 unsigned type value = in##bwl##_local(port); \
346 slow_down_io(); \
347 return value; \
348} \
349__BUILDIO(bwl,bw,type) \
350static inline void out##bwl##_p(unsigned type value, int port) { \
351 out##bwl(value, port); \
352 slow_down_io(); \
353} \
354static inline unsigned type in##bwl##_p(int port) { \
355 unsigned type value = in##bwl(port); \
356 slow_down_io(); \
357 return value; \
358} \
359static inline void outs##bwl(int port, const void *addr, unsigned long count) { \
360 __asm__ __volatile__("rep; outs" #bwl : "+S"(addr), "+c"(count) : "d"(port)); \
361} \
362static inline void ins##bwl(int port, void *addr, unsigned long count) { \
363 __asm__ __volatile__("rep; ins" #bwl : "+D"(addr), "+c"(count) : "d"(port)); \
364}
365
366BUILDIO(b,b,char)
367BUILDIO(w,w,short)
368BUILDIO(l,,int)
369
370#endif
371