diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2006-11-12 17:27:39 -0500 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2006-12-04 04:39:05 -0500 |
commit | 68a64357d15ae4f596e92715719071952006e83c (patch) | |
tree | dee519239225e92169ef77e4fad3be25c4dffe9d /include/asm-powerpc | |
parent | 3d1ea8e8cb4d497a2dd73176cc82095b8f193589 (diff) |
[POWERPC] Merge 32 and 64 bits asm-powerpc/io.h
powerpc: Merge 32 and 64 bits asm-powerpc/io.h
The rework on io.h done for the new hookable accessors made it easier,
so I just finished the work and merged 32 and 64 bits io.h for arch/powerpc.
arch/ppc still uses the old version in asm-ppc, there is just too much gunk
in there that I really can't be bothered trying to cleanup.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'include/asm-powerpc')
-rw-r--r-- | include/asm-powerpc/eeh.h | 95 | ||||
-rw-r--r-- | include/asm-powerpc/ide.h | 7 | ||||
-rw-r--r-- | include/asm-powerpc/io-defs.h | 9 | ||||
-rw-r--r-- | include/asm-powerpc/io.h | 286 | ||||
-rw-r--r-- | include/asm-powerpc/machdep.h | 4 |
5 files changed, 254 insertions, 147 deletions
diff --git a/include/asm-powerpc/eeh.h b/include/asm-powerpc/eeh.h index 66481bbf270a..b886bec67016 100644 --- a/include/asm-powerpc/eeh.h +++ b/include/asm-powerpc/eeh.h | |||
@@ -169,104 +169,19 @@ static inline u64 eeh_readq_be(const volatile void __iomem *addr) | |||
169 | return val; | 169 | return val; |
170 | } | 170 | } |
171 | 171 | ||
172 | #define EEH_CHECK_ALIGN(v,a) \ | 172 | static inline void eeh_memcpy_fromio(void *dest, const |
173 | ((((unsigned long)(v)) & ((a) - 1)) == 0) | 173 | volatile void __iomem *src, |
174 | |||
175 | static inline void eeh_memset_io(volatile void __iomem *addr, int c, | ||
176 | unsigned long n) | ||
177 | { | ||
178 | void *p = (void __force *)addr; | ||
179 | u32 lc = c; | ||
180 | lc |= lc << 8; | ||
181 | lc |= lc << 16; | ||
182 | |||
183 | __asm__ __volatile__ ("sync" : : : "memory"); | ||
184 | while(n && !EEH_CHECK_ALIGN(p, 4)) { | ||
185 | *((volatile u8 *)p) = c; | ||
186 | p++; | ||
187 | n--; | ||
188 | } | ||
189 | while(n >= 4) { | ||
190 | *((volatile u32 *)p) = lc; | ||
191 | p += 4; | ||
192 | n -= 4; | ||
193 | } | ||
194 | while(n) { | ||
195 | *((volatile u8 *)p) = c; | ||
196 | p++; | ||
197 | n--; | ||
198 | } | ||
199 | __asm__ __volatile__ ("sync" : : : "memory"); | ||
200 | } | ||
201 | static inline void eeh_memcpy_fromio(void *dest, const volatile void __iomem *src, | ||
202 | unsigned long n) | 174 | unsigned long n) |
203 | { | 175 | { |
204 | void *vsrc = (void __force *) src; | 176 | _memcpy_fromio(dest, src, n); |
205 | void *destsave = dest; | ||
206 | unsigned long nsave = n; | ||
207 | |||
208 | __asm__ __volatile__ ("sync" : : : "memory"); | ||
209 | while(n && (!EEH_CHECK_ALIGN(vsrc, 4) || !EEH_CHECK_ALIGN(dest, 4))) { | ||
210 | *((u8 *)dest) = *((volatile u8 *)vsrc); | ||
211 | __asm__ __volatile__ ("eieio" : : : "memory"); | ||
212 | vsrc++; | ||
213 | dest++; | ||
214 | n--; | ||
215 | } | ||
216 | while(n > 4) { | ||
217 | *((u32 *)dest) = *((volatile u32 *)vsrc); | ||
218 | __asm__ __volatile__ ("eieio" : : : "memory"); | ||
219 | vsrc += 4; | ||
220 | dest += 4; | ||
221 | n -= 4; | ||
222 | } | ||
223 | while(n) { | ||
224 | *((u8 *)dest) = *((volatile u8 *)vsrc); | ||
225 | __asm__ __volatile__ ("eieio" : : : "memory"); | ||
226 | vsrc++; | ||
227 | dest++; | ||
228 | n--; | ||
229 | } | ||
230 | __asm__ __volatile__ ("sync" : : : "memory"); | ||
231 | 177 | ||
232 | /* Look for ffff's here at dest[n]. Assume that at least 4 bytes | 178 | /* Look for ffff's here at dest[n]. Assume that at least 4 bytes |
233 | * were copied. Check all four bytes. | 179 | * were copied. Check all four bytes. |
234 | */ | 180 | */ |
235 | if ((nsave >= 4) && | 181 | if (n >= 4 && EEH_POSSIBLE_ERROR(*((u32 *)(dest + n - 4)), u32)) |
236 | (EEH_POSSIBLE_ERROR((*((u32 *) destsave+nsave-4)), u32))) { | 182 | eeh_check_failure(src, *((u32 *)(dest + n - 4))); |
237 | eeh_check_failure(src, (*((u32 *) destsave+nsave-4))); | ||
238 | } | ||
239 | } | 183 | } |
240 | 184 | ||
241 | static inline void eeh_memcpy_toio(volatile void __iomem *dest, const void *src, | ||
242 | unsigned long n) | ||
243 | { | ||
244 | void *vdest = (void __force *) dest; | ||
245 | |||
246 | __asm__ __volatile__ ("sync" : : : "memory"); | ||
247 | while(n && (!EEH_CHECK_ALIGN(vdest, 4) || !EEH_CHECK_ALIGN(src, 4))) { | ||
248 | *((volatile u8 *)vdest) = *((u8 *)src); | ||
249 | src++; | ||
250 | vdest++; | ||
251 | n--; | ||
252 | } | ||
253 | while(n > 4) { | ||
254 | *((volatile u32 *)vdest) = *((volatile u32 *)src); | ||
255 | src += 4; | ||
256 | vdest += 4; | ||
257 | n-=4; | ||
258 | } | ||
259 | while(n) { | ||
260 | *((volatile u8 *)vdest) = *((u8 *)src); | ||
261 | src++; | ||
262 | vdest++; | ||
263 | n--; | ||
264 | } | ||
265 | __asm__ __volatile__ ("sync" : : : "memory"); | ||
266 | } | ||
267 | |||
268 | #undef EEH_CHECK_ALIGN | ||
269 | |||
270 | /* in-string eeh macros */ | 185 | /* in-string eeh macros */ |
271 | static inline void eeh_readsb(const volatile void __iomem *addr, void * buf, | 186 | static inline void eeh_readsb(const volatile void __iomem *addr, void * buf, |
272 | int ns) | 187 | int ns) |
diff --git a/include/asm-powerpc/ide.h b/include/asm-powerpc/ide.h index 60a8fc429970..0f66f0f82c32 100644 --- a/include/asm-powerpc/ide.h +++ b/include/asm-powerpc/ide.h | |||
@@ -22,17 +22,10 @@ | |||
22 | #endif | 22 | #endif |
23 | #endif | 23 | #endif |
24 | 24 | ||
25 | #ifdef __powerpc64__ | ||
26 | #define __ide_mm_insw(p, a, c) readsw((void __iomem *)(p), (a), (c)) | 25 | #define __ide_mm_insw(p, a, c) readsw((void __iomem *)(p), (a), (c)) |
27 | #define __ide_mm_insl(p, a, c) readsl((void __iomem *)(p), (a), (c)) | 26 | #define __ide_mm_insl(p, a, c) readsl((void __iomem *)(p), (a), (c)) |
28 | #define __ide_mm_outsw(p, a, c) writesw((void __iomem *)(p), (a), (c)) | 27 | #define __ide_mm_outsw(p, a, c) writesw((void __iomem *)(p), (a), (c)) |
29 | #define __ide_mm_outsl(p, a, c) writesl((void __iomem *)(p), (a), (c)) | 28 | #define __ide_mm_outsl(p, a, c) writesl((void __iomem *)(p), (a), (c)) |
30 | #else | ||
31 | #define __ide_mm_insw(p, a, c) _insw_ns((volatile u16 __iomem *)(p), (a), (c)) | ||
32 | #define __ide_mm_insl(p, a, c) _insl_ns((volatile u32 __iomem *)(p), (a), (c)) | ||
33 | #define __ide_mm_outsw(p, a, c) _outsw_ns((volatile u16 __iomem *)(p), (a), (c)) | ||
34 | #define __ide_mm_outsl(p, a, c) _outsl_ns((volatile u32 __iomem *)(p), (a), (c)) | ||
35 | #endif | ||
36 | 29 | ||
37 | #ifndef __powerpc64__ | 30 | #ifndef __powerpc64__ |
38 | #include <linux/hdreg.h> | 31 | #include <linux/hdreg.h> |
diff --git a/include/asm-powerpc/io-defs.h b/include/asm-powerpc/io-defs.h index 5a660f1130db..03691ab69217 100644 --- a/include/asm-powerpc/io-defs.h +++ b/include/asm-powerpc/io-defs.h | |||
@@ -3,17 +3,20 @@ | |||
3 | DEF_PCI_AC_RET(readb, u8, (const PCI_IO_ADDR addr), (addr)) | 3 | DEF_PCI_AC_RET(readb, u8, (const PCI_IO_ADDR addr), (addr)) |
4 | DEF_PCI_AC_RET(readw, u16, (const PCI_IO_ADDR addr), (addr)) | 4 | DEF_PCI_AC_RET(readw, u16, (const PCI_IO_ADDR addr), (addr)) |
5 | DEF_PCI_AC_RET(readl, u32, (const PCI_IO_ADDR addr), (addr)) | 5 | DEF_PCI_AC_RET(readl, u32, (const PCI_IO_ADDR addr), (addr)) |
6 | DEF_PCI_AC_RET(readq, u64, (const PCI_IO_ADDR addr), (addr)) | ||
7 | DEF_PCI_AC_RET(readw_be, u16, (const PCI_IO_ADDR addr), (addr)) | 6 | DEF_PCI_AC_RET(readw_be, u16, (const PCI_IO_ADDR addr), (addr)) |
8 | DEF_PCI_AC_RET(readl_be, u32, (const PCI_IO_ADDR addr), (addr)) | 7 | DEF_PCI_AC_RET(readl_be, u32, (const PCI_IO_ADDR addr), (addr)) |
9 | DEF_PCI_AC_RET(readq_be, u64, (const PCI_IO_ADDR addr), (addr)) | ||
10 | DEF_PCI_AC_NORET(writeb, (u8 val, PCI_IO_ADDR addr), (val, addr)) | 8 | DEF_PCI_AC_NORET(writeb, (u8 val, PCI_IO_ADDR addr), (val, addr)) |
11 | DEF_PCI_AC_NORET(writew, (u16 val, PCI_IO_ADDR addr), (val, addr)) | 9 | DEF_PCI_AC_NORET(writew, (u16 val, PCI_IO_ADDR addr), (val, addr)) |
12 | DEF_PCI_AC_NORET(writel, (u32 val, PCI_IO_ADDR addr), (val, addr)) | 10 | DEF_PCI_AC_NORET(writel, (u32 val, PCI_IO_ADDR addr), (val, addr)) |
13 | DEF_PCI_AC_NORET(writeq, (u64 val, PCI_IO_ADDR addr), (val, addr)) | ||
14 | DEF_PCI_AC_NORET(writew_be, (u16 val, PCI_IO_ADDR addr), (val, addr)) | 11 | DEF_PCI_AC_NORET(writew_be, (u16 val, PCI_IO_ADDR addr), (val, addr)) |
15 | DEF_PCI_AC_NORET(writel_be, (u32 val, PCI_IO_ADDR addr), (val, addr)) | 12 | DEF_PCI_AC_NORET(writel_be, (u32 val, PCI_IO_ADDR addr), (val, addr)) |
13 | |||
14 | #ifdef __powerpc64__ | ||
15 | DEF_PCI_AC_RET(readq, u64, (const PCI_IO_ADDR addr), (addr)) | ||
16 | DEF_PCI_AC_RET(readq_be, u64, (const PCI_IO_ADDR addr), (addr)) | ||
17 | DEF_PCI_AC_NORET(writeq, (u64 val, PCI_IO_ADDR addr), (val, addr)) | ||
16 | DEF_PCI_AC_NORET(writeq_be, (u64 val, PCI_IO_ADDR addr), (val, addr)) | 18 | DEF_PCI_AC_NORET(writeq_be, (u64 val, PCI_IO_ADDR addr), (val, addr)) |
19 | #endif /* __powerpc64__ */ | ||
17 | 20 | ||
18 | DEF_PCI_AC_RET(inb, u8, (unsigned long port), (port)) | 21 | DEF_PCI_AC_RET(inb, u8, (unsigned long port), (port)) |
19 | DEF_PCI_AC_RET(inw, u16, (unsigned long port), (port)) | 22 | DEF_PCI_AC_RET(inw, u16, (unsigned long port), (port)) |
diff --git a/include/asm-powerpc/io.h b/include/asm-powerpc/io.h index 03e843fc1437..53bff8bd39b9 100644 --- a/include/asm-powerpc/io.h +++ b/include/asm-powerpc/io.h | |||
@@ -13,24 +13,51 @@ | |||
13 | extern int check_legacy_ioport(unsigned long base_port); | 13 | extern int check_legacy_ioport(unsigned long base_port); |
14 | #define PNPBIOS_BASE 0xf000 /* only relevant for PReP */ | 14 | #define PNPBIOS_BASE 0xf000 /* only relevant for PReP */ |
15 | 15 | ||
16 | #ifndef CONFIG_PPC64 | ||
17 | #include <asm-ppc/io.h> | ||
18 | #else | ||
19 | |||
20 | #include <linux/compiler.h> | 16 | #include <linux/compiler.h> |
21 | #include <asm/page.h> | 17 | #include <asm/page.h> |
22 | #include <asm/byteorder.h> | 18 | #include <asm/byteorder.h> |
23 | #include <asm/paca.h> | ||
24 | #include <asm/synch.h> | 19 | #include <asm/synch.h> |
25 | #include <asm/delay.h> | 20 | #include <asm/delay.h> |
21 | #include <asm/mmu.h> | ||
26 | 22 | ||
27 | #include <asm-generic/iomap.h> | 23 | #include <asm-generic/iomap.h> |
28 | 24 | ||
25 | #ifdef CONFIG_PPC64 | ||
26 | #include <asm/paca.h> | ||
27 | #endif | ||
28 | |||
29 | #define SIO_CONFIG_RA 0x398 | 29 | #define SIO_CONFIG_RA 0x398 |
30 | #define SIO_CONFIG_RD 0x399 | 30 | #define SIO_CONFIG_RD 0x399 |
31 | 31 | ||
32 | #define SLOW_DOWN_IO | 32 | #define SLOW_DOWN_IO |
33 | 33 | ||
34 | /* 32 bits uses slightly different variables for the various IO | ||
35 | * bases. Most of this file only uses _IO_BASE though which we | ||
36 | * define properly based on the platform | ||
37 | */ | ||
38 | #ifndef CONFIG_PCI | ||
39 | #define _IO_BASE 0 | ||
40 | #define _ISA_MEM_BASE 0 | ||
41 | #define PCI_DRAM_OFFSET 0 | ||
42 | #elif defined(CONFIG_PPC32) | ||
43 | #define _IO_BASE isa_io_base | ||
44 | #define _ISA_MEM_BASE isa_mem_base | ||
45 | #define PCI_DRAM_OFFSET pci_dram_offset | ||
46 | #else | ||
47 | #define _IO_BASE pci_io_base | ||
48 | #define _ISA_MEM_BASE 0 | ||
49 | #define PCI_DRAM_OFFSET 0 | ||
50 | #endif | ||
51 | |||
52 | extern unsigned long isa_io_base; | ||
53 | extern unsigned long isa_mem_base; | ||
54 | extern unsigned long pci_io_base; | ||
55 | extern unsigned long pci_dram_offset; | ||
56 | |||
57 | #if defined(CONFIG_PPC32) && defined(CONFIG_PPC_INDIRECT_IO) | ||
58 | #error CONFIG_PPC_INDIRECT_IO is not yet supported on 32 bits | ||
59 | #endif | ||
60 | |||
34 | /* | 61 | /* |
35 | * | 62 | * |
36 | * Low level MMIO accessors | 63 | * Low level MMIO accessors |
@@ -53,7 +80,11 @@ extern int check_legacy_ioport(unsigned long base_port); | |||
53 | * | 80 | * |
54 | */ | 81 | */ |
55 | 82 | ||
83 | #ifdef CONFIG_PPC64 | ||
56 | #define IO_SET_SYNC_FLAG() do { get_paca()->io_sync = 1; } while(0) | 84 | #define IO_SET_SYNC_FLAG() do { get_paca()->io_sync = 1; } while(0) |
85 | #else | ||
86 | #define IO_SET_SYNC_FLAG() | ||
87 | #endif | ||
57 | 88 | ||
58 | #define DEF_MMIO_IN(name, type, insn) \ | 89 | #define DEF_MMIO_IN(name, type, insn) \ |
59 | static inline type name(const volatile type __iomem *addr) \ | 90 | static inline type name(const volatile type __iomem *addr) \ |
@@ -86,17 +117,19 @@ static inline void name(volatile type __iomem *addr, type val) \ | |||
86 | DEF_MMIO_IN_BE(in_8, 8, lbz); | 117 | DEF_MMIO_IN_BE(in_8, 8, lbz); |
87 | DEF_MMIO_IN_BE(in_be16, 16, lhz); | 118 | DEF_MMIO_IN_BE(in_be16, 16, lhz); |
88 | DEF_MMIO_IN_BE(in_be32, 32, lwz); | 119 | DEF_MMIO_IN_BE(in_be32, 32, lwz); |
89 | DEF_MMIO_IN_BE(in_be64, 64, ld); | ||
90 | DEF_MMIO_IN_LE(in_le16, 16, lhbrx); | 120 | DEF_MMIO_IN_LE(in_le16, 16, lhbrx); |
91 | DEF_MMIO_IN_LE(in_le32, 32, lwbrx); | 121 | DEF_MMIO_IN_LE(in_le32, 32, lwbrx); |
92 | 122 | ||
93 | DEF_MMIO_OUT_BE(out_8, 8, stb); | 123 | DEF_MMIO_OUT_BE(out_8, 8, stb); |
94 | DEF_MMIO_OUT_BE(out_be16, 16, sth); | 124 | DEF_MMIO_OUT_BE(out_be16, 16, sth); |
95 | DEF_MMIO_OUT_BE(out_be32, 32, stw); | 125 | DEF_MMIO_OUT_BE(out_be32, 32, stw); |
96 | DEF_MMIO_OUT_BE(out_be64, 64, std); | ||
97 | DEF_MMIO_OUT_LE(out_le16, 16, sthbrx); | 126 | DEF_MMIO_OUT_LE(out_le16, 16, sthbrx); |
98 | DEF_MMIO_OUT_LE(out_le32, 32, stwbrx); | 127 | DEF_MMIO_OUT_LE(out_le32, 32, stwbrx); |
99 | 128 | ||
129 | #ifdef __powerpc64__ | ||
130 | DEF_MMIO_OUT_BE(out_be64, 64, std); | ||
131 | DEF_MMIO_IN_BE(in_be64, 64, ld); | ||
132 | |||
100 | /* There is no asm instructions for 64 bits reverse loads and stores */ | 133 | /* There is no asm instructions for 64 bits reverse loads and stores */ |
101 | static inline u64 in_le64(const volatile u64 __iomem *addr) | 134 | static inline u64 in_le64(const volatile u64 __iomem *addr) |
102 | { | 135 | { |
@@ -107,6 +140,7 @@ static inline void out_le64(volatile u64 __iomem *addr, u64 val) | |||
107 | { | 140 | { |
108 | out_be64(addr, cpu_to_le64(val)); | 141 | out_be64(addr, cpu_to_le64(val)); |
109 | } | 142 | } |
143 | #endif /* __powerpc64__ */ | ||
110 | 144 | ||
111 | /* | 145 | /* |
112 | * Low level IO stream instructions are defined out of line for now | 146 | * Low level IO stream instructions are defined out of line for now |
@@ -126,6 +160,17 @@ extern void _outsl_ns(volatile u32 __iomem *addr, const void *buf, long count); | |||
126 | #define _outsw _outsw_ns | 160 | #define _outsw _outsw_ns |
127 | #define _outsl _outsl_ns | 161 | #define _outsl _outsl_ns |
128 | 162 | ||
163 | |||
164 | /* | ||
165 | * memset_io, memcpy_toio, memcpy_fromio base implementations are out of line | ||
166 | */ | ||
167 | |||
168 | extern void _memset_io(volatile void __iomem *addr, int c, unsigned long n); | ||
169 | extern void _memcpy_fromio(void *dest, const volatile void __iomem *src, | ||
170 | unsigned long n); | ||
171 | extern void _memcpy_toio(volatile void __iomem *dest, const void *src, | ||
172 | unsigned long n); | ||
173 | |||
129 | /* | 174 | /* |
130 | * | 175 | * |
131 | * PCI and standard ISA accessors | 176 | * PCI and standard ISA accessors |
@@ -140,9 +185,6 @@ extern void _outsl_ns(volatile u32 __iomem *addr, const void *buf, long count); | |||
140 | * of the accessors. | 185 | * of the accessors. |
141 | */ | 186 | */ |
142 | 187 | ||
143 | extern unsigned long isa_io_base; | ||
144 | extern unsigned long pci_io_base; | ||
145 | |||
146 | 188 | ||
147 | /* | 189 | /* |
148 | * Non ordered and non-swapping "raw" accessors | 190 | * Non ordered and non-swapping "raw" accessors |
@@ -160,10 +202,6 @@ static inline unsigned int __raw_readl(const volatile void __iomem *addr) | |||
160 | { | 202 | { |
161 | return *(volatile unsigned int __force *)addr; | 203 | return *(volatile unsigned int __force *)addr; |
162 | } | 204 | } |
163 | static inline unsigned long __raw_readq(const volatile void __iomem *addr) | ||
164 | { | ||
165 | return *(volatile unsigned long __force *)addr; | ||
166 | } | ||
167 | static inline void __raw_writeb(unsigned char v, volatile void __iomem *addr) | 205 | static inline void __raw_writeb(unsigned char v, volatile void __iomem *addr) |
168 | { | 206 | { |
169 | *(volatile unsigned char __force *)addr = v; | 207 | *(volatile unsigned char __force *)addr = v; |
@@ -176,11 +214,17 @@ static inline void __raw_writel(unsigned int v, volatile void __iomem *addr) | |||
176 | { | 214 | { |
177 | *(volatile unsigned int __force *)addr = v; | 215 | *(volatile unsigned int __force *)addr = v; |
178 | } | 216 | } |
217 | |||
218 | #ifdef __powerpc64__ | ||
219 | static inline unsigned long __raw_readq(const volatile void __iomem *addr) | ||
220 | { | ||
221 | return *(volatile unsigned long __force *)addr; | ||
222 | } | ||
179 | static inline void __raw_writeq(unsigned long v, volatile void __iomem *addr) | 223 | static inline void __raw_writeq(unsigned long v, volatile void __iomem *addr) |
180 | { | 224 | { |
181 | *(volatile unsigned long __force *)addr = v; | 225 | *(volatile unsigned long __force *)addr = v; |
182 | } | 226 | } |
183 | 227 | #endif /* __powerpc64__ */ | |
184 | 228 | ||
185 | /* | 229 | /* |
186 | * | 230 | * |
@@ -188,7 +232,13 @@ static inline void __raw_writeq(unsigned long v, volatile void __iomem *addr) | |||
188 | * | 232 | * |
189 | */ | 233 | */ |
190 | 234 | ||
235 | /* | ||
236 | * Include the EEH definitions when EEH is enabled only so they don't get | ||
237 | * in the way when building for 32 bits | ||
238 | */ | ||
239 | #ifdef CONFIG_EEH | ||
191 | #include <asm/eeh.h> | 240 | #include <asm/eeh.h> |
241 | #endif | ||
192 | 242 | ||
193 | /* Shortcut to the MMIO argument pointer */ | 243 | /* Shortcut to the MMIO argument pointer */ |
194 | #define PCI_IO_ADDR volatile void __iomem * | 244 | #define PCI_IO_ADDR volatile void __iomem * |
@@ -196,7 +246,7 @@ static inline void __raw_writeq(unsigned long v, volatile void __iomem *addr) | |||
196 | /* Indirect IO address tokens: | 246 | /* Indirect IO address tokens: |
197 | * | 247 | * |
198 | * When CONFIG_PPC_INDIRECT_IO is set, the platform can provide hooks | 248 | * When CONFIG_PPC_INDIRECT_IO is set, the platform can provide hooks |
199 | * on all IOs. | 249 | * on all IOs. (Note that this is all 64 bits only for now) |
200 | * | 250 | * |
201 | * To help platforms who may need to differenciate MMIO addresses in | 251 | * To help platforms who may need to differenciate MMIO addresses in |
202 | * their hooks, a bitfield is reserved for use by the platform near the | 252 | * their hooks, a bitfield is reserved for use by the platform near the |
@@ -241,6 +291,70 @@ do { \ | |||
241 | #define PCI_FIX_ADDR(addr) (addr) | 291 | #define PCI_FIX_ADDR(addr) (addr) |
242 | #endif | 292 | #endif |
243 | 293 | ||
294 | /* | ||
295 | * On 32 bits, PIO operations have a recovery mechanism in case they trigger | ||
296 | * machine checks (which they occasionally do when probing non existing | ||
297 | * IO ports on some platforms, like PowerMac and 8xx). | ||
298 | * I always found it to be of dubious reliability and I am tempted to get | ||
299 | * rid of it one of these days. So if you think it's important to keep it, | ||
300 | * please voice up asap. We never had it for 64 bits and I do not intend | ||
301 | * to port it over | ||
302 | */ | ||
303 | |||
304 | #ifdef CONFIG_PPC32 | ||
305 | |||
306 | #define __do_in_asm(name, op) \ | ||
307 | extern __inline__ unsigned int name(unsigned int port) \ | ||
308 | { \ | ||
309 | unsigned int x; \ | ||
310 | __asm__ __volatile__( \ | ||
311 | "sync\n" \ | ||
312 | "0:" op " %0,0,%1\n" \ | ||
313 | "1: twi 0,%0,0\n" \ | ||
314 | "2: isync\n" \ | ||
315 | "3: nop\n" \ | ||
316 | "4:\n" \ | ||
317 | ".section .fixup,\"ax\"\n" \ | ||
318 | "5: li %0,-1\n" \ | ||
319 | " b 4b\n" \ | ||
320 | ".previous\n" \ | ||
321 | ".section __ex_table,\"a\"\n" \ | ||
322 | " .align 2\n" \ | ||
323 | " .long 0b,5b\n" \ | ||
324 | " .long 1b,5b\n" \ | ||
325 | " .long 2b,5b\n" \ | ||
326 | " .long 3b,5b\n" \ | ||
327 | ".previous" \ | ||
328 | : "=&r" (x) \ | ||
329 | : "r" (port + _IO_BASE)); \ | ||
330 | return x; \ | ||
331 | } | ||
332 | |||
333 | #define __do_out_asm(name, op) \ | ||
334 | extern __inline__ void name(unsigned int val, unsigned int port) \ | ||
335 | { \ | ||
336 | __asm__ __volatile__( \ | ||
337 | "sync\n" \ | ||
338 | "0:" op " %0,0,%1\n" \ | ||
339 | "1: sync\n" \ | ||
340 | "2:\n" \ | ||
341 | ".section __ex_table,\"a\"\n" \ | ||
342 | " .align 2\n" \ | ||
343 | " .long 0b,2b\n" \ | ||
344 | " .long 1b,2b\n" \ | ||
345 | ".previous" \ | ||
346 | : : "r" (val), "r" (port + _IO_BASE)); \ | ||
347 | } | ||
348 | |||
349 | __do_in_asm(_rec_inb, "lbzx") | ||
350 | __do_in_asm(_rec_inw, "lhbrx") | ||
351 | __do_in_asm(_rec_inl, "lwbrx") | ||
352 | __do_out_asm(_rec_outb, "stbx") | ||
353 | __do_out_asm(_rec_outw, "sthbrx") | ||
354 | __do_out_asm(_rec_outl, "stwbrx") | ||
355 | |||
356 | #endif /* CONFIG_PPC32 */ | ||
357 | |||
244 | /* The "__do_*" operations below provide the actual "base" implementation | 358 | /* The "__do_*" operations below provide the actual "base" implementation |
245 | * for each of the defined acccessor. Some of them use the out_* functions | 359 | * 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 | 360 | * directly, some of them still use EEH, though we might change that in the |
@@ -263,6 +377,8 @@ do { \ | |||
263 | #define __do_writew_be(val, addr) out_be16(PCI_FIX_ADDR(addr), val) | 377 | #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) | 378 | #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) | 379 | #define __do_writeq_be(val, addr) out_be64(PCI_FIX_ADDR(addr), val) |
380 | |||
381 | #ifdef CONFIG_EEH | ||
266 | #define __do_readb(addr) eeh_readb(PCI_FIX_ADDR(addr)) | 382 | #define __do_readb(addr) eeh_readb(PCI_FIX_ADDR(addr)) |
267 | #define __do_readw(addr) eeh_readw(PCI_FIX_ADDR(addr)) | 383 | #define __do_readw(addr) eeh_readw(PCI_FIX_ADDR(addr)) |
268 | #define __do_readl(addr) eeh_readl(PCI_FIX_ADDR(addr)) | 384 | #define __do_readl(addr) eeh_readl(PCI_FIX_ADDR(addr)) |
@@ -270,33 +386,64 @@ do { \ | |||
270 | #define __do_readw_be(addr) eeh_readw_be(PCI_FIX_ADDR(addr)) | 386 | #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)) | 387 | #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)) | 388 | #define __do_readq_be(addr) eeh_readq_be(PCI_FIX_ADDR(addr)) |
273 | 389 | #else /* CONFIG_EEH */ | |
274 | #define __do_outb(val, port) writeb(val,(PCI_IO_ADDR)pci_io_base+port); | 390 | #define __do_readb(addr) in_8(PCI_FIX_ADDR(addr)) |
275 | #define __do_outw(val, port) writew(val,(PCI_IO_ADDR)pci_io_base+port); | 391 | #define __do_readw(addr) in_le16(PCI_FIX_ADDR(addr)) |
276 | #define __do_outl(val, port) writel(val,(PCI_IO_ADDR)pci_io_base+port); | 392 | #define __do_readl(addr) in_le32(PCI_FIX_ADDR(addr)) |
277 | #define __do_inb(port) readb((PCI_IO_ADDR)pci_io_base + port); | 393 | #define __do_readq(addr) in_le64(PCI_FIX_ADDR(addr)) |
278 | #define __do_inw(port) readw((PCI_IO_ADDR)pci_io_base + port); | 394 | #define __do_readw_be(addr) in_be16(PCI_FIX_ADDR(addr)) |
279 | #define __do_inl(port) readl((PCI_IO_ADDR)pci_io_base + port); | 395 | #define __do_readl_be(addr) in_be32(PCI_FIX_ADDR(addr)) |
280 | 396 | #define __do_readq_be(addr) in_be64(PCI_FIX_ADDR(addr)) | |
397 | #endif /* !defined(CONFIG_EEH) */ | ||
398 | |||
399 | #ifdef CONFIG_PPC32 | ||
400 | #define __do_outb(val, port) _rec_outb(val, port) | ||
401 | #define __do_outw(val, port) _rec_outw(val, port) | ||
402 | #define __do_outl(val, port) _rec_outl(val, port) | ||
403 | #define __do_inb(port) _rec_inb(port) | ||
404 | #define __do_inw(port) _rec_inw(port) | ||
405 | #define __do_inl(port) _rec_inl(port) | ||
406 | #else /* CONFIG_PPC32 */ | ||
407 | #define __do_outb(val, port) writeb(val,(PCI_IO_ADDR)_IO_BASE+port); | ||
408 | #define __do_outw(val, port) writew(val,(PCI_IO_ADDR)_IO_BASE+port); | ||
409 | #define __do_outl(val, port) writel(val,(PCI_IO_ADDR)_IO_BASE+port); | ||
410 | #define __do_inb(port) readb((PCI_IO_ADDR)_IO_BASE + port); | ||
411 | #define __do_inw(port) readw((PCI_IO_ADDR)_IO_BASE + port); | ||
412 | #define __do_inl(port) readl((PCI_IO_ADDR)_IO_BASE + port); | ||
413 | #endif /* !CONFIG_PPC32 */ | ||
414 | |||
415 | #ifdef CONFIG_EEH | ||
281 | #define __do_readsb(a, b, n) eeh_readsb(PCI_FIX_ADDR(a), (b), (n)) | 416 | #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)) | 417 | #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)) | 418 | #define __do_readsl(a, b, n) eeh_readsl(PCI_FIX_ADDR(a), (b), (n)) |
419 | #else /* CONFIG_EEH */ | ||
420 | #define __do_readsb(a, b, n) _insb(PCI_FIX_ADDR(a), (b), (n)) | ||
421 | #define __do_readsw(a, b, n) _insw(PCI_FIX_ADDR(a), (b), (n)) | ||
422 | #define __do_readsl(a, b, n) _insl(PCI_FIX_ADDR(a), (b), (n)) | ||
423 | #endif /* !CONFIG_EEH */ | ||
284 | #define __do_writesb(a, b, n) _outsb(PCI_FIX_ADDR(a),(b),(n)) | 424 | #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)) | 425 | #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)) | 426 | #define __do_writesl(a, b, n) _outsl(PCI_FIX_ADDR(a),(b),(n)) |
287 | 427 | ||
288 | #define __do_insb(p, b, n) readsb((PCI_IO_ADDR)pci_io_base+(p), (b), (n)) | 428 | #define __do_insb(p, b, n) readsb((PCI_IO_ADDR)_IO_BASE+(p), (b), (n)) |
289 | #define __do_insw(p, b, n) readsw((PCI_IO_ADDR)pci_io_base+(p), (b), (n)) | 429 | #define __do_insw(p, b, n) readsw((PCI_IO_ADDR)_IO_BASE+(p), (b), (n)) |
290 | #define __do_insl(p, b, n) readsl((PCI_IO_ADDR)pci_io_base+(p), (b), (n)) | 430 | #define __do_insl(p, b, n) readsl((PCI_IO_ADDR)_IO_BASE+(p), (b), (n)) |
291 | #define __do_outsb(p, b, n) writesb((PCI_IO_ADDR)pci_io_base+(p),(b),(n)) | 431 | #define __do_outsb(p, b, n) writesb((PCI_IO_ADDR)_IO_BASE+(p),(b),(n)) |
292 | #define __do_outsw(p, b, n) writesw((PCI_IO_ADDR)pci_io_base+(p),(b),(n)) | 432 | #define __do_outsw(p, b, n) writesw((PCI_IO_ADDR)_IO_BASE+(p),(b),(n)) |
293 | #define __do_outsl(p, b, n) writesl((PCI_IO_ADDR)pci_io_base+(p),(b),(n)) | 433 | #define __do_outsl(p, b, n) writesl((PCI_IO_ADDR)_IO_BASE+(p),(b),(n)) |
294 | 434 | ||
295 | #define __do_memset_io(addr, c, n) eeh_memset_io(PCI_FIX_ADDR(addr), c, n) | 435 | #define __do_memset_io(addr, c, n) \ |
296 | #define __do_memcpy_fromio(dst, src, n) eeh_memcpy_fromio(dst, \ | 436 | _memset_io(PCI_FIX_ADDR(addr), c, n) |
297 | PCI_FIX_ADDR(src), n) | 437 | #define __do_memcpy_toio(dst, src, n) \ |
298 | #define __do_memcpy_toio(dst, src, n) eeh_memcpy_toio(PCI_FIX_ADDR(dst), \ | 438 | _memcpy_toio(PCI_FIX_ADDR(dst), src, n) |
299 | src, n) | 439 | |
440 | #ifdef CONFIG_EEH | ||
441 | #define __do_memcpy_fromio(dst, src, n) \ | ||
442 | eeh_memcpy_fromio(dst, PCI_FIX_ADDR(src), n) | ||
443 | #else /* CONFIG_EEH */ | ||
444 | #define __do_memcpy_fromio(dst, src, n) \ | ||
445 | _memcpy_fromio(dst,PCI_FIX_ADDR(src),n) | ||
446 | #endif /* !CONFIG_EEH */ | ||
300 | 447 | ||
301 | #ifdef CONFIG_PPC_INDIRECT_IO | 448 | #ifdef CONFIG_PPC_INDIRECT_IO |
302 | #define DEF_PCI_HOOK(x) x | 449 | #define DEF_PCI_HOOK(x) x |
@@ -343,15 +490,27 @@ static inline void name at \ | |||
343 | /* Some drivers check for the presence of readq & writeq with | 490 | /* Some drivers check for the presence of readq & writeq with |
344 | * a #ifdef, so we make them happy here. | 491 | * a #ifdef, so we make them happy here. |
345 | */ | 492 | */ |
493 | #ifdef __powerpc64__ | ||
346 | #define readq readq | 494 | #define readq readq |
347 | #define writeq writeq | 495 | #define writeq writeq |
496 | #endif | ||
497 | |||
498 | #ifdef CONFIG_NOT_COHERENT_CACHE | ||
348 | 499 | ||
349 | /* Nothing to do for cache stuff x*/ | 500 | #define dma_cache_inv(_start,_size) \ |
501 | invalidate_dcache_range(_start, (_start + _size)) | ||
502 | #define dma_cache_wback(_start,_size) \ | ||
503 | clean_dcache_range(_start, (_start + _size)) | ||
504 | #define dma_cache_wback_inv(_start,_size) \ | ||
505 | flush_dcache_range(_start, (_start + _size)) | ||
506 | |||
507 | #else /* CONFIG_NOT_COHERENT_CACHE */ | ||
350 | 508 | ||
351 | #define dma_cache_inv(_start,_size) do { } while (0) | 509 | #define dma_cache_inv(_start,_size) do { } while (0) |
352 | #define dma_cache_wback(_start,_size) do { } while (0) | 510 | #define dma_cache_wback(_start,_size) do { } while (0) |
353 | #define dma_cache_wback_inv(_start,_size) do { } while (0) | 511 | #define dma_cache_wback_inv(_start,_size) do { } while (0) |
354 | 512 | ||
513 | #endif /* !CONFIG_NOT_COHERENT_CACHE */ | ||
355 | 514 | ||
356 | /* | 515 | /* |
357 | * Convert a physical pointer to a virtual kernel pointer for /dev/mem | 516 | * Convert a physical pointer to a virtual kernel pointer for /dev/mem |
@@ -372,6 +531,9 @@ static inline void name at \ | |||
372 | #define readl_relaxed(addr) readl(addr) | 531 | #define readl_relaxed(addr) readl(addr) |
373 | #define readq_relaxed(addr) readq(addr) | 532 | #define readq_relaxed(addr) readq(addr) |
374 | 533 | ||
534 | #ifdef CONFIG_PPC32 | ||
535 | #define mmiowb() | ||
536 | #else | ||
375 | /* | 537 | /* |
376 | * Enforce synchronisation of stores vs. spin_unlock | 538 | * Enforce synchronisation of stores vs. spin_unlock |
377 | * (this does it explicitely, though our implementation of spin_unlock | 539 | * (this does it explicitely, though our implementation of spin_unlock |
@@ -385,6 +547,7 @@ static inline void mmiowb(void) | |||
385 | : "=&r" (tmp) : "i" (offsetof(struct paca_struct, io_sync)) | 547 | : "=&r" (tmp) : "i" (offsetof(struct paca_struct, io_sync)) |
386 | : "memory"); | 548 | : "memory"); |
387 | } | 549 | } |
550 | #endif /* !CONFIG_PPC32 */ | ||
388 | 551 | ||
389 | static inline void iosync(void) | 552 | static inline void iosync(void) |
390 | { | 553 | { |
@@ -453,22 +616,29 @@ static inline void iosync(void) | |||
453 | * be hooked (but can be used by a hook on iounmap) | 616 | * be hooked (but can be used by a hook on iounmap) |
454 | * | 617 | * |
455 | */ | 618 | */ |
456 | extern void __iomem *ioremap(unsigned long address, unsigned long size); | 619 | extern void __iomem *ioremap(phys_addr_t address, unsigned long size); |
457 | extern void __iomem *ioremap_flags(unsigned long address, unsigned long size, | 620 | extern void __iomem *ioremap_flags(phys_addr_t address, unsigned long size, |
458 | unsigned long flags); | 621 | unsigned long flags); |
459 | #define ioremap_nocache(addr, size) ioremap((addr), (size)) | 622 | #define ioremap_nocache(addr, size) ioremap((addr), (size)) |
460 | extern void iounmap(void __iomem *addr); | 623 | extern void iounmap(volatile void __iomem *addr); |
461 | 624 | ||
462 | extern void __iomem *__ioremap(unsigned long address, unsigned long size, | 625 | extern void __iomem *__ioremap(phys_addr_t, unsigned long size, |
463 | unsigned long flags); | 626 | unsigned long flags); |
464 | extern void __iounmap(void __iomem *addr); | 627 | extern void __iounmap(volatile void __iomem *addr); |
465 | 628 | ||
466 | extern int __ioremap_explicit(unsigned long p_addr, unsigned long v_addr, | 629 | extern int __ioremap_explicit(phys_addr_t p_addr, unsigned long v_addr, |
467 | unsigned long size, unsigned long flags); | 630 | unsigned long size, unsigned long flags); |
468 | extern int __iounmap_explicit(void __iomem *start, unsigned long size); | 631 | extern int __iounmap_explicit(volatile void __iomem *start, |
632 | unsigned long size); | ||
469 | 633 | ||
470 | extern void __iomem * reserve_phb_iospace(unsigned long size); | 634 | extern void __iomem * reserve_phb_iospace(unsigned long size); |
471 | 635 | ||
636 | /* Those are more 32 bits only functions */ | ||
637 | extern unsigned long iopa(unsigned long addr); | ||
638 | extern unsigned long mm_ptov(unsigned long addr) __attribute_const__; | ||
639 | extern void io_block_mapping(unsigned long virt, phys_addr_t phys, | ||
640 | unsigned int size, int flags); | ||
641 | |||
472 | 642 | ||
473 | /* | 643 | /* |
474 | * When CONFIG_PPC_INDIRECT_IO is set, we use the generic iomap implementation | 644 | * When CONFIG_PPC_INDIRECT_IO is set, we use the generic iomap implementation |
@@ -538,7 +708,33 @@ static inline void * phys_to_virt(unsigned long address) | |||
538 | */ | 708 | */ |
539 | #define BIO_VMERGE_BOUNDARY 0 | 709 | #define BIO_VMERGE_BOUNDARY 0 |
540 | 710 | ||
711 | /* | ||
712 | * 32 bits still uses virt_to_bus() for it's implementation of DMA | ||
713 | * mappings se we have to keep it defined here. We also have some old | ||
714 | * drivers (shame shame shame) that use bus_to_virt() and haven't been | ||
715 | * fixed yet so I need to define it here. | ||
716 | */ | ||
717 | #ifdef CONFIG_PPC32 | ||
718 | |||
719 | static inline unsigned long virt_to_bus(volatile void * address) | ||
720 | { | ||
721 | if (address == NULL) | ||
722 | return 0; | ||
723 | return __pa(address) + PCI_DRAM_OFFSET; | ||
724 | } | ||
725 | |||
726 | static inline void * bus_to_virt(unsigned long address) | ||
727 | { | ||
728 | if (address == 0) | ||
729 | return NULL; | ||
730 | return __va(address - PCI_DRAM_OFFSET); | ||
731 | } | ||
732 | |||
733 | #define page_to_bus(page) (page_to_phys(page) + PCI_DRAM_OFFSET) | ||
734 | |||
735 | #endif /* CONFIG_PPC32 */ | ||
736 | |||
737 | |||
541 | #endif /* __KERNEL__ */ | 738 | #endif /* __KERNEL__ */ |
542 | 739 | ||
543 | #endif /* CONFIG_PPC64 */ | ||
544 | #endif /* _ASM_POWERPC_IO_H */ | 740 | #endif /* _ASM_POWERPC_IO_H */ |
diff --git a/include/asm-powerpc/machdep.h b/include/asm-powerpc/machdep.h index 8c1a2dfe5cc7..1b04e5723548 100644 --- a/include/asm-powerpc/machdep.h +++ b/include/asm-powerpc/machdep.h | |||
@@ -88,9 +88,9 @@ struct machdep_calls { | |||
88 | void (*pci_dma_dev_setup)(struct pci_dev *dev); | 88 | void (*pci_dma_dev_setup)(struct pci_dev *dev); |
89 | void (*pci_dma_bus_setup)(struct pci_bus *bus); | 89 | void (*pci_dma_bus_setup)(struct pci_bus *bus); |
90 | 90 | ||
91 | void __iomem * (*ioremap)(unsigned long addr, unsigned long size, | 91 | void __iomem * (*ioremap)(phys_addr_t addr, unsigned long size, |
92 | unsigned long flags); | 92 | unsigned long flags); |
93 | void (*iounmap)(void __iomem *token); | 93 | void (*iounmap)(volatile void __iomem *token); |
94 | #endif /* CONFIG_PPC64 */ | 94 | #endif /* CONFIG_PPC64 */ |
95 | 95 | ||
96 | int (*probe)(void); | 96 | int (*probe)(void); |