From c3455b0efc2b5b1bdc755602f77ce7f43725bf61 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Thu, 30 Jun 2005 10:48:40 +0000 Subject: Inline ioremap() calls for constant addresses that map to KSEG1. Signed-off-by: Ralf Baechle --- include/asm-mips/io.h | 31 +++++++++++++++++++++++++++++-- include/asm-mips/mach-au1x00/ioremap.h | 30 ++++++++++++++++++++++++++++++ include/asm-mips/mach-generic/ioremap.h | 23 +++++++++++++++++++++++ 3 files changed, 82 insertions(+), 2 deletions(-) create mode 100644 include/asm-mips/mach-au1x00/ioremap.h create mode 100644 include/asm-mips/mach-generic/ioremap.h (limited to 'include') 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 @@ #include #include +#include #include /* @@ -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 000000000000..f1c8c1087115 --- /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 +#include + +#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 000000000000..9b64ff6e485d --- /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 + +/* + * 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 */ -- cgit v1.2.3