]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - include/asm-powerpc/io.h
powerpc: Improve (in|out)_[bl]eXX() asm code
[linux-2.6-omap-h63xx.git] / include / asm-powerpc / io.h
index 7be26f615755ad5a80c84aa3867facf781f3db03..6db422d8e2a0944c64aafdbe5cc20aac6e093ec0 100644 (file)
@@ -2,7 +2,7 @@
 #define _ASM_POWERPC_IO_H
 #ifdef __KERNEL__
 
-/* 
+/*
  * 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
@@ -18,6 +18,9 @@ extern int check_legacy_ioport(unsigned long base_port);
 #define _PNPWRP                0xa79
 #define PNPBIOS_BASE   0xf000
 
+#include <linux/device.h>
+#include <linux/io.h>
+
 #include <linux/compiler.h>
 #include <asm/page.h>
 #include <asm/byteorder.h>
@@ -92,33 +95,60 @@ extern resource_size_t isa_mem_base;
 #define IO_SET_SYNC_FLAG()
 #endif
 
-#define DEF_MMIO_IN(name, type, insn)                                  \
-static inline type name(const volatile type __iomem *addr)             \
+/* gcc 4.0 and older doesn't have 'Z' constraint */
+#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ == 0)
+#define DEF_MMIO_IN_LE(name, size, insn)                               \
+static inline u##size name(const volatile u##size __iomem *addr)       \
 {                                                                      \
-       type ret;                                                       \
-       __asm__ __volatile__("sync;" insn ";twi 0,%0,0;isync"           \
-               : "=r" (ret) : "r" (addr), "m" (*addr));                \
+       u##size ret;                                                    \
+       __asm__ __volatile__("sync;"#insn" %0,0,%1;twi 0,%0,0;isync"    \
+               : "=r" (ret) : "r" (addr), "m" (*addr) : "memory");     \
        return ret;                                                     \
 }
 
-#define DEF_MMIO_OUT(name, type, insn)                                 \
-static inline void name(volatile type __iomem *addr, type val)         \
+#define DEF_MMIO_OUT_LE(name, size, insn)                              \
+static inline void name(volatile u##size __iomem *addr, u##size val)   \
+{                                                                      \
+       __asm__ __volatile__("sync;"#insn" %1,0,%2"                     \
+               : "=m" (*addr) : "r" (val), "r" (addr) : "memory");     \
+       IO_SET_SYNC_FLAG();                                             \
+}
+#else /* newer gcc */
+#define DEF_MMIO_IN_LE(name, size, insn)                               \
+static inline u##size name(const volatile u##size __iomem *addr)       \
 {                                                                      \
-       __asm__ __volatile__("sync;" insn                               \
-               : "=m" (*addr) : "r" (val), "r" (addr));                \
-       IO_SET_SYNC_FLAG();                                     \
+       u##size ret;                                                    \
+       __asm__ __volatile__("sync;"#insn" %0,%y1;twi 0,%0,0;isync"     \
+               : "=r" (ret) : "Z" (*addr) : "memory");                 \
+       return ret;                                                     \
 }
 
+#define DEF_MMIO_OUT_LE(name, size, insn)                              \
+static inline void name(volatile u##size __iomem *addr, u##size val)   \
+{                                                                      \
+       __asm__ __volatile__("sync;"#insn" %1,%y0"                      \
+               : "=Z" (*addr) : "r" (val) : "memory");                 \
+       IO_SET_SYNC_FLAG();                                             \
+}
+#endif
 
-#define DEF_MMIO_IN_BE(name, size, insn) \
-       DEF_MMIO_IN(name, u##size, __stringify(insn)"%U2%X2 %0,%2")
-#define DEF_MMIO_IN_LE(name, size, insn) \
-       DEF_MMIO_IN(name, u##size, __stringify(insn)" %0,0,%1")
+#define DEF_MMIO_IN_BE(name, size, insn)                               \
+static inline u##size name(const volatile u##size __iomem *addr)       \
+{                                                                      \
+       u##size ret;                                                    \
+       __asm__ __volatile__("sync;"#insn"%U1%X1 %0,%1;twi 0,%0,0;isync"\
+               : "=r" (ret) : "m" (*addr) : "memory");                 \
+       return ret;                                                     \
+}
+
+#define DEF_MMIO_OUT_BE(name, size, insn)                              \
+static inline void name(volatile u##size __iomem *addr, u##size val)   \
+{                                                                      \
+       __asm__ __volatile__("sync;"#insn"%U0%X0 %1,%0"                 \
+               : "=m" (*addr) : "r" (val) : "memory");                 \
+       IO_SET_SYNC_FLAG();                                             \
+}
 
-#define DEF_MMIO_OUT_BE(name, size, insn) \
-       DEF_MMIO_OUT(name, u##size, __stringify(insn)"%U0%X0 %1,%0")
-#define DEF_MMIO_OUT_LE(name, size, insn) \
-       DEF_MMIO_OUT(name, u##size, __stringify(insn)" %1,0,%2")
 
 DEF_MMIO_IN_BE(in_8,     8, lbz);
 DEF_MMIO_IN_BE(in_be16, 16, lhz);
@@ -330,7 +360,8 @@ static inline unsigned int name(unsigned int port)  \
                "       .long   3b,5b\n"                \
                ".previous"                             \
                : "=&r" (x)                             \
-               : "r" (port + _IO_BASE));               \
+               : "r" (port + _IO_BASE)                 \
+               : "memory");                            \
        return x;                                       \
 }
 
@@ -347,7 +378,8 @@ static inline void name(unsigned int val, unsigned int port) \
                "       .long   0b,2b\n"                \
                "       .long   1b,2b\n"                \
                ".previous"                             \
-               : : "r" (val), "r" (port + _IO_BASE));  \
+               : : "r" (val), "r" (port + _IO_BASE)    \
+               : "memory");                            \
 }
 
 __do_in_asm(_rec_inb, "lbzx")
@@ -458,8 +490,8 @@ __do_out_asm(_rec_outl, "stwbrx")
 /* Structure containing all the hooks */
 extern struct ppc_pci_io {
 
-#define DEF_PCI_AC_RET(name, ret, at, al)      ret (*name) at;
-#define DEF_PCI_AC_NORET(name, at, al)         void (*name) at;
+#define DEF_PCI_AC_RET(name, ret, at, al, space, aa)   ret (*name) at;
+#define DEF_PCI_AC_NORET(name, at, al, space, aa)      void (*name) at;
 
 #include <asm/io-defs.h>
 
@@ -469,7 +501,7 @@ extern struct ppc_pci_io {
 } ppc_pci_io;
 
 /* The inline wrappers */
-#define DEF_PCI_AC_RET(name, ret, at, al)                      \
+#define DEF_PCI_AC_RET(name, ret, at, al, space, aa)           \
 static inline ret name at                                      \
 {                                                              \
        if (DEF_PCI_HOOK(ppc_pci_io.name) != NULL)              \
@@ -477,7 +509,7 @@ static inline ret name at                                   \
        return __do_##name al;                                  \
 }
 
-#define DEF_PCI_AC_NORET(name, at, al)                         \
+#define DEF_PCI_AC_NORET(name, at, al, space, aa)              \
 static inline void name at                                     \
 {                                                              \
        if (DEF_PCI_HOOK(ppc_pci_io.name) != NULL)              \
@@ -744,6 +776,9 @@ static inline void * bus_to_virt(unsigned long address)
 
 #define clrsetbits_8(addr, clear, set) clrsetbits(8, addr, clear, set)
 
+void __iomem *devm_ioremap_prot(struct device *dev, resource_size_t offset,
+                               size_t size, unsigned long flags);
+
 #endif /* __KERNEL__ */
 
 #endif /* _ASM_POWERPC_IO_H */