aboutsummaryrefslogtreecommitdiffstats
path: root/include/asm-powerpc/io.h
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2006-11-11 01:25:10 -0500
committerPaul Mackerras <paulus@samba.org>2006-12-04 04:38:52 -0500
commit4cb3cee03d558fd457cb58f56c80a2a09a66110c (patch)
treefe903107d098871a7babc1e3432448758c542cde /include/asm-powerpc/io.h
parentd03f387eb321189bc2ba278b6ca82f1a45cf19d6 (diff)
[POWERPC] Allow hooking of PCI MMIO & PIO accessors on 64 bits
This patch reworks the way iSeries hooks on PCI IO operations (both MMIO and PIO) and provides a generic way for other platforms to do so (we have need to do that for various other platforms). While reworking the IO ops, I ended up doing some spring cleaning in io.h and eeh.h which I might want to split into 2 or 3 patches (among others, eeh.h had a lot of useless stuff in it). A side effect is that EEH for PIO should work now (it used to pass IO ports down to the eeh address check functions which is bogus). Also, new are MMIO "repeat" ops, which other archs like ARM already had, and that we have too now: readsb, readsw, readsl, writesb, writesw, writesl. In the long run, I might also make EEH use the hooks instead of wrapping at the toplevel, which would make things even cleaner and relegate EEH completely in platforms/iseries, but we have to measure the performance impact there (though it's really only on MMIO reads) Since I also need to hook on ioremap, I shuffled the functions a bit there. I introduced ioremap_flags() to use by drivers who want to pass explicit flags to ioremap (and it can be hooked). The old __ioremap() is still there as a low level and cannot be hooked, thus drivers who use it should migrate unless they know they want the low level version. The patch "arch provides generic iomap missing accessors" (should be number 4 in this series) is a pre-requisite to provide full iomap API support with this patch. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'include/asm-powerpc/io.h')
-rw-r--r--include/asm-powerpc/io.h641
1 files changed, 377 insertions, 264 deletions
diff --git a/include/asm-powerpc/io.h b/include/asm-powerpc/io.h
index c2c5f14b5f5f..03e843fc1437 100644
--- a/include/asm-powerpc/io.h
+++ b/include/asm-powerpc/io.h
@@ -31,57 +31,122 @@ extern int check_legacy_ioport(unsigned long base_port);
31 31
32#define SLOW_DOWN_IO 32#define SLOW_DOWN_IO
33 33
34/*
35 *
36 * Low level MMIO accessors
37 *
38 * This provides the non-bus specific accessors to MMIO. Those are PowerPC
39 * specific and thus shouldn't be used in generic code. The accessors
40 * provided here are:
41 *
42 * in_8, in_le16, in_be16, in_le32, in_be32, in_le64, in_be64
43 * out_8, out_le16, out_be16, out_le32, out_be32, out_le64, out_be64
44 * _insb, _insw_ns, _insl_ns, _outsb, _outsw_ns, _outsl_ns
45 *
46 * Those operate directly on a kernel virtual address. Note that the prototype
47 * for the out_* accessors has the arguments in opposite order from the usual
48 * linux PCI accessors. Unlike those, they take the address first and the value
49 * next.
50 *
51 * Note: I might drop the _ns suffix on the stream operations soon as it is
52 * simply normal for stream operations to not swap in the first place.
53 *
54 */
55
56#define IO_SET_SYNC_FLAG() do { get_paca()->io_sync = 1; } while(0)
57
58#define DEF_MMIO_IN(name, type, insn) \
59static inline type name(const volatile type __iomem *addr) \
60{ \
61 type ret; \
62 __asm__ __volatile__("sync;" insn ";twi 0,%0,0;isync" \
63 : "=r" (ret) : "r" (addr), "m" (*addr)); \
64 return ret; \
65}
66
67#define DEF_MMIO_OUT(name, type, insn) \
68static inline void name(volatile type __iomem *addr, type val) \
69{ \
70 __asm__ __volatile__("sync;" insn \
71 : "=m" (*addr) : "r" (val), "r" (addr)); \
72 IO_SET_SYNC_FLAG(); \
73}
74
75
76#define DEF_MMIO_IN_BE(name, size, insn) \
77 DEF_MMIO_IN(name, u##size, __stringify(insn)"%U2%X2 %0,%2")
78#define DEF_MMIO_IN_LE(name, size, insn) \
79 DEF_MMIO_IN(name, u##size, __stringify(insn)" %0,0,%1")
80
81#define DEF_MMIO_OUT_BE(name, size, insn) \
82 DEF_MMIO_OUT(name, u##size, __stringify(insn)"%U0%X0 %1,%0")
83#define DEF_MMIO_OUT_LE(name, size, insn) \
84 DEF_MMIO_OUT(name, u##size, __stringify(insn)" %1,0,%2")
85
86DEF_MMIO_IN_BE(in_8, 8, lbz);
87DEF_MMIO_IN_BE(in_be16, 16, lhz);
88DEF_MMIO_IN_BE(in_be32, 32, lwz);
89DEF_MMIO_IN_BE(in_be64, 64, ld);
90DEF_MMIO_IN_LE(in_le16, 16, lhbrx);
91DEF_MMIO_IN_LE(in_le32, 32, lwbrx);
92
93DEF_MMIO_OUT_BE(out_8, 8, stb);
94DEF_MMIO_OUT_BE(out_be16, 16, sth);
95DEF_MMIO_OUT_BE(out_be32, 32, stw);
96DEF_MMIO_OUT_BE(out_be64, 64, std);
97DEF_MMIO_OUT_LE(out_le16, 16, sthbrx);
98DEF_MMIO_OUT_LE(out_le32, 32, stwbrx);
99
100/* There is no asm instructions for 64 bits reverse loads and stores */
101static inline u64 in_le64(const volatile u64 __iomem *addr)
102{
103 return le64_to_cpu(in_be64(addr));
104}
105
106static inline void out_le64(volatile u64 __iomem *addr, u64 val)
107{
108 out_be64(addr, cpu_to_le64(val));
109}
110
111/*
112 * Low level IO stream instructions are defined out of line for now
113 */
114extern void _insb(const volatile u8 __iomem *addr, void *buf, long count);
115extern void _outsb(volatile u8 __iomem *addr,const void *buf,long count);
116extern void _insw_ns(const volatile u16 __iomem *addr, void *buf, long count);
117extern void _outsw_ns(volatile u16 __iomem *addr, const void *buf, long count);
118extern void _insl_ns(const volatile u32 __iomem *addr, void *buf, long count);
119extern void _outsl_ns(volatile u32 __iomem *addr, const void *buf, long count);
120
121/* The _ns naming is historical and will be removed. For now, just #define
122 * the non _ns equivalent names
123 */
124#define _insw _insw_ns
125#define _insl _insl_ns
126#define _outsw _outsw_ns
127#define _outsl _outsl_ns
128
129/*
130 *
131 * PCI and standard ISA accessors
132 *
133 * Those are globally defined linux accessors for devices on PCI or ISA
134 * busses. They follow the Linux defined semantics. The current implementation
135 * for PowerPC is as close as possible to the x86 version of these, and thus
136 * provides fairly heavy weight barriers for the non-raw versions
137 *
138 * In addition, they support a hook mechanism when CONFIG_PPC_INDIRECT_IO
139 * allowing the platform to provide its own implementation of some or all
140 * of the accessors.
141 */
142
34extern unsigned long isa_io_base; 143extern unsigned long isa_io_base;
35extern unsigned long pci_io_base; 144extern unsigned long pci_io_base;
36 145
37#ifdef CONFIG_PPC_ISERIES 146
38 147/*
39extern int in_8(const volatile unsigned char __iomem *addr); 148 * Non ordered and non-swapping "raw" accessors
40extern void out_8(volatile unsigned char __iomem *addr, int val); 149 */
41extern int in_le16(const volatile unsigned short __iomem *addr);
42extern int in_be16(const volatile unsigned short __iomem *addr);
43extern void out_le16(volatile unsigned short __iomem *addr, int val);
44extern void out_be16(volatile unsigned short __iomem *addr, int val);
45extern unsigned in_le32(const volatile unsigned __iomem *addr);
46extern unsigned in_be32(const volatile unsigned __iomem *addr);
47extern void out_le32(volatile unsigned __iomem *addr, int val);
48extern void out_be32(volatile unsigned __iomem *addr, int val);
49extern unsigned long in_le64(const volatile unsigned long __iomem *addr);
50extern unsigned long in_be64(const volatile unsigned long __iomem *addr);
51extern void out_le64(volatile unsigned long __iomem *addr, unsigned long val);
52extern void out_be64(volatile unsigned long __iomem *addr, unsigned long val);
53
54extern unsigned char __raw_readb(const volatile void __iomem *addr);
55extern unsigned short __raw_readw(const volatile void __iomem *addr);
56extern unsigned int __raw_readl(const volatile void __iomem *addr);
57extern unsigned long __raw_readq(const volatile void __iomem *addr);
58extern void __raw_writeb(unsigned char v, volatile void __iomem *addr);
59extern void __raw_writew(unsigned short v, volatile void __iomem *addr);
60extern void __raw_writel(unsigned int v, volatile void __iomem *addr);
61extern void __raw_writeq(unsigned long v, volatile void __iomem *addr);
62
63extern void memset_io(volatile void __iomem *addr, int c, unsigned long n);
64extern void memcpy_fromio(void *dest, const volatile void __iomem *src,
65 unsigned long n);
66extern void memcpy_toio(volatile void __iomem *dest, const void *src,
67 unsigned long n);
68
69#else /* CONFIG_PPC_ISERIES */
70
71#define in_8(addr) __in_8((addr))
72#define out_8(addr, val) __out_8((addr), (val))
73#define in_le16(addr) __in_le16((addr))
74#define in_be16(addr) __in_be16((addr))
75#define out_le16(addr, val) __out_le16((addr), (val))
76#define out_be16(addr, val) __out_be16((addr), (val))
77#define in_le32(addr) __in_le32((addr))
78#define in_be32(addr) __in_be32((addr))
79#define out_le32(addr, val) __out_le32((addr), (val))
80#define out_be32(addr, val) __out_be32((addr), (val))
81#define in_le64(addr) __in_le64((addr))
82#define in_be64(addr) __in_be64((addr))
83#define out_le64(addr, val) __out_le64((addr), (val))
84#define out_be64(addr, val) __out_be64((addr), (val))
85 150
86static inline unsigned char __raw_readb(const volatile void __iomem *addr) 151static inline unsigned char __raw_readb(const volatile void __iomem *addr)
87{ 152{
@@ -115,52 +180,203 @@ static inline void __raw_writeq(unsigned long v, volatile void __iomem *addr)
115{ 180{
116 *(volatile unsigned long __force *)addr = v; 181 *(volatile unsigned long __force *)addr = v;
117} 182}
118#define memset_io(a,b,c) eeh_memset_io((a),(b),(c))
119#define memcpy_fromio(a,b,c) eeh_memcpy_fromio((a),(b),(c))
120#define memcpy_toio(a,b,c) eeh_memcpy_toio((a),(b),(c))
121 183
122#endif /* CONFIG_PPC_ISERIES */
123 184
124/* 185/*
125 * The insw/outsw/insl/outsl macros don't do byte-swapping. 186 *
126 * They are only used in practice for transferring buffers which 187 * PCI PIO and MMIO accessors.
127 * are arrays of bytes, and byte-swapping is not appropriate in 188 *
128 * that case. - paulus */ 189 */
129#define insb(port, buf, ns) eeh_insb((port), (buf), (ns)) 190
130#define insw(port, buf, ns) eeh_insw_ns((port), (buf), (ns)) 191#include <asm/eeh.h>
131#define insl(port, buf, nl) eeh_insl_ns((port), (buf), (nl)) 192
132 193/* Shortcut to the MMIO argument pointer */
133#define outsb(port, buf, ns) _outsb((u8 __iomem *)((port)+pci_io_base), (buf), (ns)) 194#define PCI_IO_ADDR volatile void __iomem *
134#define outsw(port, buf, ns) _outsw_ns((u16 __iomem *)((port)+pci_io_base), (buf), (ns)) 195
135#define outsl(port, buf, nl) _outsl_ns((u32 __iomem *)((port)+pci_io_base), (buf), (nl)) 196/* Indirect IO address tokens:
136 197 *
137#define readb(addr) eeh_readb(addr) 198 * When CONFIG_PPC_INDIRECT_IO is set, the platform can provide hooks
138#define readw(addr) eeh_readw(addr) 199 * on all IOs.
139#define readl(addr) eeh_readl(addr) 200 *
140#define readq(addr) eeh_readq(addr) 201 * To help platforms who may need to differenciate MMIO addresses in
141#define writeb(data, addr) eeh_writeb((data), (addr)) 202 * their hooks, a bitfield is reserved for use by the platform near the
142#define writew(data, addr) eeh_writew((data), (addr)) 203 * top of MMIO addresses (not PIO, those have to cope the hard way).
143#define writel(data, addr) eeh_writel((data), (addr)) 204 *
144#define writeq(data, addr) eeh_writeq((data), (addr)) 205 * This bit field is 12 bits and is at the top of the IO virtual
145#define inb(port) eeh_inb((unsigned long)port) 206 * addresses PCI_IO_INDIRECT_TOKEN_MASK.
146#define outb(val, port) eeh_outb(val, (unsigned long)port) 207 *
147#define inw(port) eeh_inw((unsigned long)port) 208 * The kernel virtual space is thus:
148#define outw(val, port) eeh_outw(val, (unsigned long)port) 209 *
149#define inl(port) eeh_inl((unsigned long)port) 210 * 0xD000000000000000 : vmalloc
150#define outl(val, port) eeh_outl(val, (unsigned long)port) 211 * 0xD000080000000000 : PCI PHB IO space
212 * 0xD000080080000000 : ioremap
213 * 0xD0000fffffffffff : end of ioremap region
214 *
215 * Since the top 4 bits are reserved as the region ID, we use thus
216 * the next 12 bits and keep 4 bits available for the future if the
217 * virtual address space is ever to be extended.
218 *
219 * The direct IO mapping operations will then mask off those bits
220 * before doing the actual access, though that only happen when
221 * CONFIG_PPC_INDIRECT_IO is set, thus be careful when you use that
222 * mechanism
223 */
224
225#ifdef CONFIG_PPC_INDIRECT_IO
226#define PCI_IO_IND_TOKEN_MASK 0x0fff000000000000ul
227#define PCI_IO_IND_TOKEN_SHIFT 48
228#define PCI_FIX_ADDR(addr) \
229 ((PCI_IO_ADDR)(((unsigned long)(addr)) & ~PCI_IO_IND_TOKEN_MASK))
230#define PCI_GET_ADDR_TOKEN(addr) \
231 (((unsigned long)(addr) & PCI_IO_IND_TOKEN_MASK) >> \
232 PCI_IO_IND_TOKEN_SHIFT)
233#define PCI_SET_ADDR_TOKEN(addr, token) \
234do { \
235 unsigned long __a = (unsigned long)(addr); \
236 __a &= ~PCI_IO_IND_TOKEN_MASK; \
237 __a |= ((unsigned long)(token)) << PCI_IO_IND_TOKEN_SHIFT; \
238 (addr) = (void __iomem *)__a; \
239} while(0)
240#else
241#define PCI_FIX_ADDR(addr) (addr)
242#endif
243
244/* The "__do_*" operations below provide the actual "base" implementation
245 * for each of the defined acccessor. Some of them use the out_* functions
246 * directly, some of them still use EEH, though we might change that in the
247 * future. Those macros below provide the necessary argument swapping and
248 * handling of the IO base for PIO.
249 *
250 * They are themselves used by the macros that define the actual accessors
251 * and can be used by the hooks if any.
252 *
253 * Note that PIO operations are always defined in terms of their corresonding
254 * MMIO operations. That allows platforms like iSeries who want to modify the
255 * behaviour of both to only hook on the MMIO version and get both. It's also
256 * possible to hook directly at the toplevel PIO operation if they have to
257 * be handled differently
258 */
259#define __do_writeb(val, addr) out_8(PCI_FIX_ADDR(addr), val)
260#define __do_writew(val, addr) out_le16(PCI_FIX_ADDR(addr), val)
261#define __do_writel(val, addr) out_le32(PCI_FIX_ADDR(addr), val)
262#define __do_writeq(val, addr) out_le64(PCI_FIX_ADDR(addr), val)
263#define __do_writew_be(val, addr) out_be16(PCI_FIX_ADDR(addr), val)
264#define __do_writel_be(val, addr) out_be32(PCI_FIX_ADDR(addr), val)
265#define __do_writeq_be(val, addr) out_be64(PCI_FIX_ADDR(addr), val)
266#define __do_readb(addr) eeh_readb(PCI_FIX_ADDR(addr))
267#define __do_readw(addr) eeh_readw(PCI_FIX_ADDR(addr))
268#define __do_readl(addr) eeh_readl(PCI_FIX_ADDR(addr))
269#define __do_readq(addr) eeh_readq(PCI_FIX_ADDR(addr))
270#define __do_readw_be(addr) eeh_readw_be(PCI_FIX_ADDR(addr))
271#define __do_readl_be(addr) eeh_readl_be(PCI_FIX_ADDR(addr))
272#define __do_readq_be(addr) eeh_readq_be(PCI_FIX_ADDR(addr))
273
274#define __do_outb(val, port) writeb(val,(PCI_IO_ADDR)pci_io_base+port);
275#define __do_outw(val, port) writew(val,(PCI_IO_ADDR)pci_io_base+port);
276#define __do_outl(val, port) writel(val,(PCI_IO_ADDR)pci_io_base+port);
277#define __do_inb(port) readb((PCI_IO_ADDR)pci_io_base + port);
278#define __do_inw(port) readw((PCI_IO_ADDR)pci_io_base + port);
279#define __do_inl(port) readl((PCI_IO_ADDR)pci_io_base + port);
280
281#define __do_readsb(a, b, n) eeh_readsb(PCI_FIX_ADDR(a), (b), (n))
282#define __do_readsw(a, b, n) eeh_readsw(PCI_FIX_ADDR(a), (b), (n))
283#define __do_readsl(a, b, n) eeh_readsl(PCI_FIX_ADDR(a), (b), (n))
284#define __do_writesb(a, b, n) _outsb(PCI_FIX_ADDR(a),(b),(n))
285#define __do_writesw(a, b, n) _outsw(PCI_FIX_ADDR(a),(b),(n))
286#define __do_writesl(a, b, n) _outsl(PCI_FIX_ADDR(a),(b),(n))
287
288#define __do_insb(p, b, n) readsb((PCI_IO_ADDR)pci_io_base+(p), (b), (n))
289#define __do_insw(p, b, n) readsw((PCI_IO_ADDR)pci_io_base+(p), (b), (n))
290#define __do_insl(p, b, n) readsl((PCI_IO_ADDR)pci_io_base+(p), (b), (n))
291#define __do_outsb(p, b, n) writesb((PCI_IO_ADDR)pci_io_base+(p),(b),(n))
292#define __do_outsw(p, b, n) writesw((PCI_IO_ADDR)pci_io_base+(p),(b),(n))
293#define __do_outsl(p, b, n) writesl((PCI_IO_ADDR)pci_io_base+(p),(b),(n))
294
295#define __do_memset_io(addr, c, n) eeh_memset_io(PCI_FIX_ADDR(addr), c, n)
296#define __do_memcpy_fromio(dst, src, n) eeh_memcpy_fromio(dst, \
297 PCI_FIX_ADDR(src), n)
298#define __do_memcpy_toio(dst, src, n) eeh_memcpy_toio(PCI_FIX_ADDR(dst), \
299 src, n)
300
301#ifdef CONFIG_PPC_INDIRECT_IO
302#define DEF_PCI_HOOK(x) x
303#else
304#define DEF_PCI_HOOK(x) NULL
305#endif
306
307/* Structure containing all the hooks */
308extern struct ppc_pci_io {
309
310#define DEF_PCI_AC_RET(name, ret, at, al) ret (*name) at;
311#define DEF_PCI_AC_NORET(name, at, al) void (*name) at;
312
313#include <asm/io-defs.h>
314
315#undef DEF_PCI_AC_RET
316#undef DEF_PCI_AC_NORET
317
318} ppc_pci_io;
319
320/* The inline wrappers */
321#define DEF_PCI_AC_RET(name, ret, at, al) \
322static inline ret name at \
323{ \
324 if (DEF_PCI_HOOK(ppc_pci_io.name) != NULL) \
325 return ppc_pci_io.name al; \
326 return __do_##name al; \
327}
328
329#define DEF_PCI_AC_NORET(name, at, al) \
330static inline void name at \
331{ \
332 if (DEF_PCI_HOOK(ppc_pci_io.name) != NULL) \
333 ppc_pci_io.name al; \
334 else \
335 __do_##name al; \
336}
337
338#include <asm/io-defs.h>
339
340#undef DEF_PCI_AC_RET
341#undef DEF_PCI_AC_NORET
342
343/* Some drivers check for the presence of readq & writeq with
344 * a #ifdef, so we make them happy here.
345 */
346#define readq readq
347#define writeq writeq
348
349/* Nothing to do for cache stuff x*/
350
351#define dma_cache_inv(_start,_size) do { } while (0)
352#define dma_cache_wback(_start,_size) do { } while (0)
353#define dma_cache_wback_inv(_start,_size) do { } while (0)
354
355
356/*
357 * Convert a physical pointer to a virtual kernel pointer for /dev/mem
358 * access
359 */
360#define xlate_dev_mem_ptr(p) __va(p)
361
362/*
363 * Convert a virtual cached pointer to an uncached pointer
364 */
365#define xlate_dev_kmem_ptr(p) p
151 366
367/*
368 * We don't do relaxed operations yet, at least not with this semantic
369 */
152#define readb_relaxed(addr) readb(addr) 370#define readb_relaxed(addr) readb(addr)
153#define readw_relaxed(addr) readw(addr) 371#define readw_relaxed(addr) readw(addr)
154#define readl_relaxed(addr) readl(addr) 372#define readl_relaxed(addr) readl(addr)
155#define readq_relaxed(addr) readq(addr) 373#define readq_relaxed(addr) readq(addr)
156 374
157extern void _insb(volatile u8 __iomem *port, void *buf, long count); 375/*
158extern void _outsb(volatile u8 __iomem *port, const void *buf, long count); 376 * Enforce synchronisation of stores vs. spin_unlock
159extern void _insw_ns(volatile u16 __iomem *port, void *buf, long count); 377 * (this does it explicitely, though our implementation of spin_unlock
160extern void _outsw_ns(volatile u16 __iomem *port, const void *buf, long count); 378 * does it implicitely too)
161extern void _insl_ns(volatile u32 __iomem *port, void *buf, long count); 379 */
162extern void _outsl_ns(volatile u32 __iomem *port, const void *buf, long count);
163
164static inline void mmiowb(void) 380static inline void mmiowb(void)
165{ 381{
166 unsigned long tmp; 382 unsigned long tmp;
@@ -170,6 +386,23 @@ static inline void mmiowb(void)
170 : "memory"); 386 : "memory");
171} 387}
172 388
389static inline void iosync(void)
390{
391 __asm__ __volatile__ ("sync" : : : "memory");
392}
393
394/* Enforce in-order execution of data I/O.
395 * No distinction between read/write on PPC; use eieio for all three.
396 * Those are fairly week though. They don't provide a barrier between
397 * MMIO and cacheable storage nor do they provide a barrier vs. locks,
398 * they only provide barriers between 2 __raw MMIO operations and
399 * possibly break write combining.
400 */
401#define iobarrier_rw() eieio()
402#define iobarrier_r() eieio()
403#define iobarrier_w() eieio()
404
405
173/* 406/*
174 * output pause versions need a delay at least for the 407 * output pause versions need a delay at least for the
175 * w83c105 ide controller in a p610. 408 * w83c105 ide controller in a p610.
@@ -185,11 +418,6 @@ static inline void mmiowb(void)
185#define IO_SPACE_LIMIT ~(0UL) 418#define IO_SPACE_LIMIT ~(0UL)
186 419
187 420
188extern int __ioremap_explicit(unsigned long p_addr, unsigned long v_addr,
189 unsigned long size, unsigned long flags);
190extern void __iomem *__ioremap(unsigned long address, unsigned long size,
191 unsigned long flags);
192
193/** 421/**
194 * ioremap - map bus memory into CPU space 422 * ioremap - map bus memory into CPU space
195 * @address: bus address of the memory 423 * @address: bus address of the memory
@@ -200,14 +428,70 @@ extern void __iomem *__ioremap(unsigned long address, unsigned long size,
200 * writew/writel functions and the other mmio helpers. The returned 428 * writew/writel functions and the other mmio helpers. The returned
201 * address is not guaranteed to be usable directly as a virtual 429 * address is not guaranteed to be usable directly as a virtual
202 * address. 430 * address.
431 *
432 * We provide a few variations of it:
433 *
434 * * ioremap is the standard one and provides non-cacheable guarded mappings
435 * and can be hooked by the platform via ppc_md
436 *
437 * * ioremap_flags allows to specify the page flags as an argument and can
438 * also be hooked by the platform via ppc_md
439 *
440 * * ioremap_nocache is identical to ioremap
441 *
442 * * iounmap undoes such a mapping and can be hooked
443 *
444 * * __ioremap_explicit (and the pending __iounmap_explicit) are low level
445 * functions to create hand-made mappings for use only by the PCI code
446 * and cannot currently be hooked.
447 *
448 * * __ioremap is the low level implementation used by ioremap and
449 * ioremap_flags and cannot be hooked (but can be used by a hook on one
450 * of the previous ones)
451 *
452 * * __iounmap, is the low level implementation used by iounmap and cannot
453 * be hooked (but can be used by a hook on iounmap)
454 *
203 */ 455 */
204extern void __iomem *ioremap(unsigned long address, unsigned long size); 456extern void __iomem *ioremap(unsigned long address, unsigned long size);
205 457extern void __iomem *ioremap_flags(unsigned long address, unsigned long size,
458 unsigned long flags);
206#define ioremap_nocache(addr, size) ioremap((addr), (size)) 459#define ioremap_nocache(addr, size) ioremap((addr), (size))
207extern int iounmap_explicit(volatile void __iomem *addr, unsigned long size); 460extern void iounmap(void __iomem *addr);
208extern void iounmap(volatile void __iomem *addr); 461
462extern void __iomem *__ioremap(unsigned long address, unsigned long size,
463 unsigned long flags);
464extern void __iounmap(void __iomem *addr);
465
466extern int __ioremap_explicit(unsigned long p_addr, unsigned long v_addr,
467 unsigned long size, unsigned long flags);
468extern int __iounmap_explicit(void __iomem *start, unsigned long size);
469
209extern void __iomem * reserve_phb_iospace(unsigned long size); 470extern void __iomem * reserve_phb_iospace(unsigned long size);
210 471
472
473/*
474 * When CONFIG_PPC_INDIRECT_IO is set, we use the generic iomap implementation
475 * which needs some additional definitions here. They basically allow PIO
476 * space overall to be 1GB. This will work as long as we never try to use
477 * iomap to map MMIO below 1GB which should be fine on ppc64
478 */
479#define HAVE_ARCH_PIO_SIZE 1
480#define PIO_OFFSET 0x00000000UL
481#define PIO_MASK 0x3fffffffUL
482#define PIO_RESERVED 0x40000000UL
483
484#define mmio_read16be(addr) readw_be(addr)
485#define mmio_read32be(addr) readl_be(addr)
486#define mmio_write16be(val, addr) writew_be(val, addr)
487#define mmio_write32be(val, addr) writel_be(val, addr)
488#define mmio_insb(addr, dst, count) readsb(addr, dst, count)
489#define mmio_insw(addr, dst, count) readsw(addr, dst, count)
490#define mmio_insl(addr, dst, count) readsl(addr, dst, count)
491#define mmio_outsb(addr, src, count) writesb(addr, src, count)
492#define mmio_outsw(addr, src, count) writesw(addr, src, count)
493#define mmio_outsl(addr, src, count) writesl(addr, src, count)
494
211/** 495/**
212 * virt_to_phys - map virtual addresses to physical 496 * virt_to_phys - map virtual addresses to physical
213 * @address: address to remap 497 * @address: address to remap
@@ -254,177 +538,6 @@ static inline void * phys_to_virt(unsigned long address)
254 */ 538 */
255#define BIO_VMERGE_BOUNDARY 0 539#define BIO_VMERGE_BOUNDARY 0
256 540
257static inline void iosync(void)
258{
259 __asm__ __volatile__ ("sync" : : : "memory");
260}
261
262/* Enforce in-order execution of data I/O.
263 * No distinction between read/write on PPC; use eieio for all three.
264 */
265#define iobarrier_rw() eieio()
266#define iobarrier_r() eieio()
267#define iobarrier_w() eieio()
268
269/*
270 * 8, 16 and 32 bit, big and little endian I/O operations, with barrier.
271 * These routines do not perform EEH-related I/O address translation,
272 * and should not be used directly by device drivers. Use inb/readb
273 * instead.
274 */
275static inline int __in_8(const volatile unsigned char __iomem *addr)
276{
277 int ret;
278
279 __asm__ __volatile__("sync; lbz%U1%X1 %0,%1; twi 0,%0,0; isync"
280 : "=r" (ret) : "m" (*addr));
281 return ret;
282}
283
284static inline void __out_8(volatile unsigned char __iomem *addr, int val)
285{
286 __asm__ __volatile__("sync; stb%U0%X0 %1,%0"
287 : "=m" (*addr) : "r" (val));
288 get_paca()->io_sync = 1;
289}
290
291static inline int __in_le16(const volatile unsigned short __iomem *addr)
292{
293 int ret;
294
295 __asm__ __volatile__("sync; lhbrx %0,0,%1; twi 0,%0,0; isync"
296 : "=r" (ret) : "r" (addr), "m" (*addr));
297 return ret;
298}
299
300static inline int __in_be16(const volatile unsigned short __iomem *addr)
301{
302 int ret;
303
304 __asm__ __volatile__("sync; lhz%U1%X1 %0,%1; twi 0,%0,0; isync"
305 : "=r" (ret) : "m" (*addr));
306 return ret;
307}
308
309static inline void __out_le16(volatile unsigned short __iomem *addr, int val)
310{
311 __asm__ __volatile__("sync; sthbrx %1,0,%2"
312 : "=m" (*addr) : "r" (val), "r" (addr));
313 get_paca()->io_sync = 1;
314}
315
316static inline void __out_be16(volatile unsigned short __iomem *addr, int val)
317{
318 __asm__ __volatile__("sync; sth%U0%X0 %1,%0"
319 : "=m" (*addr) : "r" (val));
320 get_paca()->io_sync = 1;
321}
322
323static inline unsigned __in_le32(const volatile unsigned __iomem *addr)
324{
325 unsigned ret;
326
327 __asm__ __volatile__("sync; lwbrx %0,0,%1; twi 0,%0,0; isync"
328 : "=r" (ret) : "r" (addr), "m" (*addr));
329 return ret;
330}
331
332static inline unsigned __in_be32(const volatile unsigned __iomem *addr)
333{
334 unsigned ret;
335
336 __asm__ __volatile__("sync; lwz%U1%X1 %0,%1; twi 0,%0,0; isync"
337 : "=r" (ret) : "m" (*addr));
338 return ret;
339}
340
341static inline void __out_le32(volatile unsigned __iomem *addr, int val)
342{
343 __asm__ __volatile__("sync; stwbrx %1,0,%2" : "=m" (*addr)
344 : "r" (val), "r" (addr));
345 get_paca()->io_sync = 1;
346}
347
348static inline void __out_be32(volatile unsigned __iomem *addr, int val)
349{
350 __asm__ __volatile__("sync; stw%U0%X0 %1,%0"
351 : "=m" (*addr) : "r" (val));
352 get_paca()->io_sync = 1;
353}
354
355static inline unsigned long __in_le64(const volatile unsigned long __iomem *addr)
356{
357 unsigned long tmp, ret;
358
359 __asm__ __volatile__(
360 "sync\n"
361 "ld %1,0(%2)\n"
362 "twi 0,%1,0\n"
363 "isync\n"
364 "rldimi %0,%1,5*8,1*8\n"
365 "rldimi %0,%1,3*8,2*8\n"
366 "rldimi %0,%1,1*8,3*8\n"
367 "rldimi %0,%1,7*8,4*8\n"
368 "rldicl %1,%1,32,0\n"
369 "rlwimi %0,%1,8,8,31\n"
370 "rlwimi %0,%1,24,16,23\n"
371 : "=r" (ret) , "=r" (tmp) : "b" (addr) , "m" (*addr));
372 return ret;
373}
374
375static inline unsigned long __in_be64(const volatile unsigned long __iomem *addr)
376{
377 unsigned long ret;
378
379 __asm__ __volatile__("sync; ld%U1%X1 %0,%1; twi 0,%0,0; isync"
380 : "=r" (ret) : "m" (*addr));
381 return ret;
382}
383
384static inline void __out_le64(volatile unsigned long __iomem *addr, unsigned long val)
385{
386 unsigned long tmp;
387
388 __asm__ __volatile__(
389 "rldimi %0,%1,5*8,1*8\n"
390 "rldimi %0,%1,3*8,2*8\n"
391 "rldimi %0,%1,1*8,3*8\n"
392 "rldimi %0,%1,7*8,4*8\n"
393 "rldicl %1,%1,32,0\n"
394 "rlwimi %0,%1,8,8,31\n"
395 "rlwimi %0,%1,24,16,23\n"
396 "sync\n"
397 "std %0,0(%3)"
398 : "=&r" (tmp) , "=&r" (val) : "1" (val) , "b" (addr) , "m" (*addr));
399 get_paca()->io_sync = 1;
400}
401
402static inline void __out_be64(volatile unsigned long __iomem *addr, unsigned long val)
403{
404 __asm__ __volatile__("sync; std%U0%X0 %1,%0" : "=m" (*addr) : "r" (val));
405 get_paca()->io_sync = 1;
406}
407
408#include <asm/eeh.h>
409
410/* Nothing to do */
411
412#define dma_cache_inv(_start,_size) do { } while (0)
413#define dma_cache_wback(_start,_size) do { } while (0)
414#define dma_cache_wback_inv(_start,_size) do { } while (0)
415
416
417/*
418 * Convert a physical pointer to a virtual kernel pointer for /dev/mem
419 * access
420 */
421#define xlate_dev_mem_ptr(p) __va(p)
422
423/*
424 * Convert a virtual cached pointer to an uncached pointer
425 */
426#define xlate_dev_kmem_ptr(p) p
427
428#endif /* __KERNEL__ */ 541#endif /* __KERNEL__ */
429 542
430#endif /* CONFIG_PPC64 */ 543#endif /* CONFIG_PPC64 */