diff options
author | Maciej W. Rozycki <macro@linux-mips.org> | 2005-06-30 10:48:40 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2005-10-29 19:31:34 +0100 |
commit | c3455b0efc2b5b1bdc755602f77ce7f43725bf61 (patch) | |
tree | 835ffe4b5509053c0623146157d92c4ca2d32aea /include | |
parent | c134a5ecdb8f4aee09feca0d4d395915e752fcb8 (diff) |
Inline ioremap() calls for constant addresses that map to KSEG1.
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'include')
-rw-r--r-- | include/asm-mips/io.h | 31 | ||||
-rw-r--r-- | include/asm-mips/mach-au1x00/ioremap.h | 30 | ||||
-rw-r--r-- | include/asm-mips/mach-generic/ioremap.h | 23 |
3 files changed, 82 insertions, 2 deletions
diff --git a/include/asm-mips/io.h b/include/asm-mips/io.h index 3b4d97d8064..42f80782acd 100644 --- a/include/asm-mips/io.h +++ b/include/asm-mips/io.h @@ -27,6 +27,7 @@ #include <asm/processor.h> #include <asm/string.h> +#include <ioremap.h> #include <mangle-port.h> /* @@ -209,6 +210,8 @@ extern void __iounmap(volatile void __iomem *addr); static inline void __iomem * __ioremap_mode(phys_t offset, unsigned long size, unsigned long flags) { +#define __IS_LOW512(addr) (!((phys_t)(addr) & (phys_t) ~0x1fffffffULL)) + if (cpu_has_64bit_addresses) { u64 base = UNCAC_BASE; @@ -219,9 +222,29 @@ static inline void __iomem * __ioremap_mode(phys_t offset, unsigned long size, if (flags == _CACHE_UNCACHED) base = (u64) IO_BASE; return (void __iomem *) (unsigned long) (base + offset); + } else if (__builtin_constant_p(offset) && + __builtin_constant_p(size) && __builtin_constant_p(flags)) { + phys_t phys_addr, last_addr; + + phys_addr = fixup_bigphys_addr(offset, size); + + /* Don't allow wraparound or zero size. */ + last_addr = phys_addr + size - 1; + if (!size || last_addr < phys_addr) + return NULL; + + /* + * Map uncached objects in the low 512MB of address + * space using KSEG1. + */ + if (__IS_LOW512(phys_addr) && __IS_LOW512(last_addr) && + flags == _CACHE_UNCACHED) + return (void __iomem *)CKSEG1ADDR(phys_addr); } return __ioremap(offset, size, flags); + +#undef __IS_LOW512 } /* @@ -273,12 +296,16 @@ static inline void __iomem * __ioremap_mode(phys_t offset, unsigned long size, static inline void iounmap(volatile void __iomem *addr) { - if (cpu_has_64bit_addresses) +#define __IS_KSEG1(addr) (((unsigned long)(addr) & ~0x1fffffffUL) == CKSEG1) + + if (cpu_has_64bit_addresses || + (__builtin_constant_p(addr) && __IS_KSEG1(addr))) return; __iounmap(addr); -} +#undef __IS_KSEG1 +} #define __BUILD_MEMORY_SINGLE(pfx, bwlq, type, irq) \ \ diff --git a/include/asm-mips/mach-au1x00/ioremap.h b/include/asm-mips/mach-au1x00/ioremap.h new file mode 100644 index 00000000000..f1c8c108711 --- /dev/null +++ b/include/asm-mips/mach-au1x00/ioremap.h @@ -0,0 +1,30 @@ +/* + * include/asm-mips/mach-au1x00/ioremap.h + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#ifndef __ASM_MACH_AU1X00_IOREMAP_H +#define __ASM_MACH_AU1X00_IOREMAP_H + +#include <linux/config.h> +#include <linux/types.h> + +#ifndef CONFIG_64BIT_PHYS_ADDR +static inline phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size) +{ + return phys_addr; +} +#endif + +/* + * Allow physical addresses to be fixed up to help 36-bit peripherals. + */ +static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size) +{ + return __fixup_bigphys_addr(phys_addr, size); +} + +#endif /* __ASM_MACH_AU1X00_IOREMAP_H */ diff --git a/include/asm-mips/mach-generic/ioremap.h b/include/asm-mips/mach-generic/ioremap.h new file mode 100644 index 00000000000..9b64ff6e485 --- /dev/null +++ b/include/asm-mips/mach-generic/ioremap.h @@ -0,0 +1,23 @@ +/* + * include/asm-mips/mach-generic/ioremap.h + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#ifndef __ASM_MACH_GENERIC_IOREMAP_H +#define __ASM_MACH_GENERIC_IOREMAP_H + +#include <linux/types.h> + +/* + * Allow physical addresses to be fixed up to help peripherals located + * outside the low 32-bit range -- generic pass-through version. + */ +static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size) +{ + return phys_addr; +} + +#endif /* __ASM_MACH_GENERIC_IOREMAP_H */ |