aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/asm-mips/io.h31
-rw-r--r--include/asm-mips/mach-au1x00/ioremap.h30
-rw-r--r--include/asm-mips/mach-generic/ioremap.h23
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 */