|
|
|
@ -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 |
|
|
|
|