ppc4xx: Update in_be32() functions and friends to latest Linux version
authorStefan Roese <sr@denx.de>
Fri, 1 Jun 2007 13:16:58 +0000 (15:16 +0200)
committerStefan Roese <sr@denx.de>
Fri, 1 Jun 2007 13:16:58 +0000 (15:16 +0200)
Signed-off-by: Stefan Roese <sr@denx.de>
include/asm-ppc/io.h

index bbc9ba0..03289bc 100644 (file)
@@ -105,6 +105,11 @@ static inline void sync(void)
        __asm__ __volatile__ ("sync" : : : "memory");
 }
 
+static inline void isync(void)
+{
+       __asm__ __volatile__ ("isync" : : : "memory");
+}
+
 /* Enforce in-order execution of data I/O.
  * No distinction between read/write on PPC; use eieio for all three.
  */
@@ -114,74 +119,90 @@ static inline void sync(void)
 
 /*
  * 8, 16 and 32 bit, big and little endian I/O operations, with barrier.
+ *
+ * Read operations have additional twi & isync to make sure the read
+ * is actually performed (i.e. the data has come back) before we start
+ * executing any following instructions.
  */
-extern inline int in_8(volatile u8 *addr)
+#define __iomem
+extern inline int in_8(const volatile unsigned char __iomem *addr)
 {
-    int ret;
+       int ret;
 
-    __asm__ __volatile__("lbz%U1%X1 %0,%1; eieio" : "=r" (ret) : "m" (*addr));
-    return ret;
+       __asm__ __volatile__(
+               "sync; lbz%U1%X1 %0,%1;\n"
+               "twi 0,%0,0;\n"
+               "isync" : "=r" (ret) : "m" (*addr));
+       return ret;
 }
 
-extern inline void out_8(volatile u8 *addr, int val)
+extern inline void out_8(volatile unsigned char __iomem *addr, int val)
 {
-    __asm__ __volatile__("stb%U0%X0 %1,%0; eieio" : "=m" (*addr) : "r" (val));
+       __asm__ __volatile__("stb%U0%X0 %1,%0; eieio" : "=m" (*addr) : "r" (val));
 }
 
-extern inline int in_le16(volatile u16 *addr)
+extern inline int in_le16(const volatile unsigned short __iomem *addr)
 {
-    int ret;
+       int ret;
 
-    __asm__ __volatile__("lhbrx %0,0,%1; eieio" : "=r" (ret) :
-                 "r" (addr), "m" (*addr));
-    return ret;
+       __asm__ __volatile__("sync; lhbrx %0,0,%1;\n"
+                            "twi 0,%0,0;\n"
+                            "isync" : "=r" (ret) :
+                             "r" (addr), "m" (*addr));
+       return ret;
 }
 
-extern inline int in_be16(volatile u16 *addr)
+extern inline int in_be16(const volatile unsigned short __iomem *addr)
 {
-    int ret;
+       int ret;
 
-    __asm__ __volatile__("lhz%U1%X1 %0,%1; eieio" : "=r" (ret) : "m" (*addr));
-    return ret;
+       __asm__ __volatile__("sync; lhz%U1%X1 %0,%1;\n"
+                            "twi 0,%0,0;\n"
+                            "isync" : "=r" (ret) : "m" (*addr));
+       return ret;
 }
 
-extern inline void out_le16(volatile u16 *addr, int val)
+extern inline void out_le16(volatile unsigned short __iomem *addr, int val)
 {
-    __asm__ __volatile__("sthbrx %1,0,%2; eieio" : "=m" (*addr) :
-                 "r" (val), "r" (addr));
+       __asm__ __volatile__("sync; sthbrx %1,0,%2" : "=m" (*addr) :
+                             "r" (val), "r" (addr));
 }
 
-extern inline void out_be16(volatile u16 *addr, int val)
+extern inline void out_be16(volatile unsigned short __iomem *addr, int val)
 {
-    __asm__ __volatile__("sth%U0%X0 %1,%0; eieio" : "=m" (*addr) : "r" (val));
+       __asm__ __volatile__("sync; sth%U0%X0 %1,%0" : "=m" (*addr) : "r" (val));
 }
 
-extern inline unsigned in_le32(volatile u32 *addr)
+extern inline unsigned in_le32(const volatile unsigned __iomem *addr)
 {
-    unsigned ret;
+       unsigned ret;
 
-    __asm__ __volatile__("lwbrx %0,0,%1; eieio" : "=r" (ret) :
-                "r" (addr), "m" (*addr));
-    return ret;
+       __asm__ __volatile__("sync; lwbrx %0,0,%1;\n"
+                            "twi 0,%0,0;\n"
+                            "isync" : "=r" (ret) :
+                            "r" (addr), "m" (*addr));
+       return ret;
 }
 
-extern inline unsigned in_be32(volatile u32 *addr)
+extern inline unsigned in_be32(const volatile unsigned __iomem *addr)
 {
-    unsigned ret;
+       unsigned ret;
 
-    __asm__ __volatile__("lwz%U1%X1 %0,%1; eieio" : "=r" (ret) : "m" (*addr));
-    return ret;
+       __asm__ __volatile__("sync; lwz%U1%X1 %0,%1;\n"
+                            "twi 0,%0,0;\n"
+                            "isync" : "=r" (ret) : "m" (*addr));
+       return ret;
 }
 
-extern inline void out_le32(volatile unsigned *addr, int val)
+extern inline void out_le32(volatile unsigned __iomem *addr, int val)
 {
-    __asm__ __volatile__("stwbrx %1,0,%2; eieio" : "=m" (*addr) :
-                "r" (val), "r" (addr));
+       __asm__ __volatile__("sync; stwbrx %1,0,%2" : "=m" (*addr) :
+                            "r" (val), "r" (addr));
 }
 
-extern inline void out_be32(volatile unsigned *addr, int val)
+extern inline void out_be32(volatile unsigned __iomem *addr, int val)
 {
-    __asm__ __volatile__("stw%U0%X0 %1,%0; eieio" : "=m" (*addr) : "r" (val));
+       __asm__ __volatile__("sync; stw%U0%X0 %1,%0" : "=m" (*addr) : "r" (val));
 }
 
 #endif