diff options
Diffstat (limited to 'include/asm-mips/io.h')
-rw-r--r-- | include/asm-mips/io.h | 31 |
1 files changed, 29 insertions, 2 deletions
diff --git a/include/asm-mips/io.h b/include/asm-mips/io.h index 3b4d97d80643..42f80782acd2 100644 --- a/include/asm-mips/io.h +++ b/include/asm-mips/io.h | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <asm/processor.h> | 27 | #include <asm/processor.h> |
28 | #include <asm/string.h> | 28 | #include <asm/string.h> |
29 | 29 | ||
30 | #include <ioremap.h> | ||
30 | #include <mangle-port.h> | 31 | #include <mangle-port.h> |
31 | 32 | ||
32 | /* | 33 | /* |
@@ -209,6 +210,8 @@ extern void __iounmap(volatile void __iomem *addr); | |||
209 | static inline void __iomem * __ioremap_mode(phys_t offset, unsigned long size, | 210 | static inline void __iomem * __ioremap_mode(phys_t offset, unsigned long size, |
210 | unsigned long flags) | 211 | unsigned long flags) |
211 | { | 212 | { |
213 | #define __IS_LOW512(addr) (!((phys_t)(addr) & (phys_t) ~0x1fffffffULL)) | ||
214 | |||
212 | if (cpu_has_64bit_addresses) { | 215 | if (cpu_has_64bit_addresses) { |
213 | u64 base = UNCAC_BASE; | 216 | u64 base = UNCAC_BASE; |
214 | 217 | ||
@@ -219,9 +222,29 @@ static inline void __iomem * __ioremap_mode(phys_t offset, unsigned long size, | |||
219 | if (flags == _CACHE_UNCACHED) | 222 | if (flags == _CACHE_UNCACHED) |
220 | base = (u64) IO_BASE; | 223 | base = (u64) IO_BASE; |
221 | return (void __iomem *) (unsigned long) (base + offset); | 224 | return (void __iomem *) (unsigned long) (base + offset); |
225 | } else if (__builtin_constant_p(offset) && | ||
226 | __builtin_constant_p(size) && __builtin_constant_p(flags)) { | ||
227 | phys_t phys_addr, last_addr; | ||
228 | |||
229 | phys_addr = fixup_bigphys_addr(offset, size); | ||
230 | |||
231 | /* Don't allow wraparound or zero size. */ | ||
232 | last_addr = phys_addr + size - 1; | ||
233 | if (!size || last_addr < phys_addr) | ||
234 | return NULL; | ||
235 | |||
236 | /* | ||
237 | * Map uncached objects in the low 512MB of address | ||
238 | * space using KSEG1. | ||
239 | */ | ||
240 | if (__IS_LOW512(phys_addr) && __IS_LOW512(last_addr) && | ||
241 | flags == _CACHE_UNCACHED) | ||
242 | return (void __iomem *)CKSEG1ADDR(phys_addr); | ||
222 | } | 243 | } |
223 | 244 | ||
224 | return __ioremap(offset, size, flags); | 245 | return __ioremap(offset, size, flags); |
246 | |||
247 | #undef __IS_LOW512 | ||
225 | } | 248 | } |
226 | 249 | ||
227 | /* | 250 | /* |
@@ -273,12 +296,16 @@ static inline void __iomem * __ioremap_mode(phys_t offset, unsigned long size, | |||
273 | 296 | ||
274 | static inline void iounmap(volatile void __iomem *addr) | 297 | static inline void iounmap(volatile void __iomem *addr) |
275 | { | 298 | { |
276 | if (cpu_has_64bit_addresses) | 299 | #define __IS_KSEG1(addr) (((unsigned long)(addr) & ~0x1fffffffUL) == CKSEG1) |
300 | |||
301 | if (cpu_has_64bit_addresses || | ||
302 | (__builtin_constant_p(addr) && __IS_KSEG1(addr))) | ||
277 | return; | 303 | return; |
278 | 304 | ||
279 | __iounmap(addr); | 305 | __iounmap(addr); |
280 | } | ||
281 | 306 | ||
307 | #undef __IS_KSEG1 | ||
308 | } | ||
282 | 309 | ||
283 | #define __BUILD_MEMORY_SINGLE(pfx, bwlq, type, irq) \ | 310 | #define __BUILD_MEMORY_SINGLE(pfx, bwlq, type, irq) \ |
284 | \ | 311 | \ |