* for more details.
*
* Copyright (C) 1994, 1995 Waldorf GmbH
- * Copyright (C) 1994 - 2000 Ralf Baechle
+ * Copyright (C) 1994 - 2000, 06 Ralf Baechle
* Copyright (C) 1999, 2000 Silicon Graphics, Inc.
* Copyright (C) 2004, 2005 MIPS Technologies, Inc. All rights reserved.
* Author: Maciej W. Rozycki <macro@mips.com>
#include <linux/types.h>
#include <asm/addrspace.h>
-#include <asm/bug.h>
#include <asm/byteorder.h>
#include <asm/cpu.h>
#include <asm/cpu-features.h>
* variations of functions: non-prefixed ones that preserve the value
* and prefixed ones that preserve byte addresses. The latters are
* typically used for moving raw data between a peripheral and memory (cf.
- * string I/O functions), hence the "mem_" prefix.
+ * string I/O functions), hence the "__mem_" prefix.
*/
#if defined(CONFIG_SWAP_IO_SPACE)
# define ioswabb(x) (x)
-# define mem_ioswabb(x) (x)
+# define __mem_ioswabb(x) (x)
# ifdef CONFIG_SGI_IP22
/*
* IP22 seems braindead enough to swap 16bits values in hardware, but
* not 32bits. Go figure... Can't tell without documentation.
*/
# define ioswabw(x) (x)
-# define mem_ioswabw(x) le16_to_cpu(x)
+# define __mem_ioswabw(x) le16_to_cpu(x)
# else
# define ioswabw(x) le16_to_cpu(x)
-# define mem_ioswabw(x) (x)
+# define __mem_ioswabw(x) (x)
# endif
# define ioswabl(x) le32_to_cpu(x)
-# define mem_ioswabl(x) (x)
+# define __mem_ioswabl(x) (x)
# define ioswabq(x) le64_to_cpu(x)
-# define mem_ioswabq(x) (x)
+# define __mem_ioswabq(x) (x)
#else
# define ioswabb(x) (x)
-# define mem_ioswabb(x) (x)
+# define __mem_ioswabb(x) (x)
# define ioswabw(x) (x)
-# define mem_ioswabw(x) cpu_to_le16(x)
+# define __mem_ioswabw(x) cpu_to_le16(x)
# define ioswabl(x) (x)
-# define mem_ioswabl(x) cpu_to_le32(x)
+# define __mem_ioswabl(x) cpu_to_le32(x)
# define ioswabq(x) (x)
-# define mem_ioswabq(x) cpu_to_le32(x)
+# define __mem_ioswabq(x) cpu_to_le32(x)
#endif
*/
extern const unsigned long mips_io_port_base;
-#define set_io_port_base(base) \
- do { * (unsigned long *) &mips_io_port_base = (base); } while (0)
+/*
+ * Gcc will generate code to load the value of mips_io_port_base after each
+ * function call which may be fairly wasteful in some cases. So we don't
+ * play quite by the book. We tell gcc mips_io_port_base is a long variable
+ * which solves the code generation issue. Now we need to violate the
+ * aliasing rules a little to make initialization possible and finally we
+ * will need the barrier() to fight side effects of the aliasing chat.
+ * This trickery will eventually collapse under gcc's optimizer. Oh well.
+ */
+static inline void set_io_port_base(unsigned long base)
+{
+ * (unsigned long *) &mips_io_port_base = base;
+ barrier();
+}
/*
* Thanks to James van Artsdalen for a better timing-fix than
#define ioremap_nocache(offset, size) \
__ioremap_mode((offset), (size), _CACHE_UNCACHED)
+/*
+ * ioremap_cachable - map bus memory into CPU space
+ * @offset: bus address of the memory
+ * @size: size of the resource to map
+ *
+ * ioremap_nocache performs a platform specific sequence of operations to
+ * make bus memory CPU accessible via the readb/readw/readl/writeb/
+ * writew/writel functions and the other mmio helpers. The returned
+ * address is not guaranteed to be usable directly as a virtual
+ * address.
+ *
+ * This version of ioremap ensures that the memory is marked cachable by
+ * the CPU. Also enables full write-combining. Useful for some
+ * memory-like regions on I/O busses.
+ */
+#define ioremap_cachable(offset, size) \
+ __ioremap_mode((offset), (size), PAGE_CACHABLE_DEFAULT)
+
/*
* These two are MIPS specific ioremap variant. ioremap_cacheable_cow
* requests a cachable mapping, ioremap_uncached_accelerated requests a
BUG(); \
} \
\
-static inline type pfx##read##bwlq(volatile void __iomem *mem) \
+static inline type pfx##read##bwlq(const volatile void __iomem *mem) \
{ \
volatile type *__mem; \
type __val; \
\
__BUILD_MEMORY_PFX(__raw_, bwlq, type) \
__BUILD_MEMORY_PFX(, bwlq, type) \
-__BUILD_MEMORY_PFX(mem_, bwlq, type) \
+__BUILD_MEMORY_PFX(__mem_, bwlq, type) \
BUILDIO_MEM(b, u8)
BUILDIO_MEM(w, u16)
#define BUILDIO_IOPORT(bwlq, type) \
__BUILD_IOPORT_PFX(, bwlq, type) \
- __BUILD_IOPORT_PFX(mem_, bwlq, type)
+ __BUILD_IOPORT_PFX(__mem_, bwlq, type)
BUILDIO_IOPORT(b, u8)
BUILDIO_IOPORT(w, u16)
#define __BUILD_MEMORY_STRING(bwlq, type) \
\
-static inline void writes##bwlq(volatile void __iomem *mem, void *addr, \
- unsigned int count) \
+static inline void writes##bwlq(volatile void __iomem *mem, \
+ const void *addr, unsigned int count) \
{ \
- volatile type *__addr = addr; \
+ const volatile type *__addr = addr; \
\
while (count--) { \
- mem_write##bwlq(*__addr, mem); \
+ __mem_write##bwlq(*__addr, mem); \
__addr++; \
} \
} \
volatile type *__addr = addr; \
\
while (count--) { \
- *__addr = mem_read##bwlq(mem); \
+ *__addr = __mem_read##bwlq(mem); \
__addr++; \
} \
}
const volatile type *__addr = addr; \
\
while (count--) { \
- mem_out##bwlq(*__addr, port); \
+ __mem_out##bwlq(*__addr, port); \
__addr++; \
} \
} \
volatile type *__addr = addr; \
\
while (count--) { \
- *__addr = mem_in##bwlq(port); \
+ *__addr = __mem_in##bwlq(port); \
__addr++; \
} \
}