diff options
-rw-r--r-- | include/asm-powerpc/io.h | 57 |
1 files changed, 42 insertions, 15 deletions
diff --git a/include/asm-powerpc/io.h b/include/asm-powerpc/io.h index 89189488e286..6db422d8e2a0 100644 --- a/include/asm-powerpc/io.h +++ b/include/asm-powerpc/io.h | |||
@@ -95,33 +95,60 @@ extern resource_size_t isa_mem_base; | |||
95 | #define IO_SET_SYNC_FLAG() | 95 | #define IO_SET_SYNC_FLAG() |
96 | #endif | 96 | #endif |
97 | 97 | ||
98 | #define DEF_MMIO_IN(name, type, insn) \ | 98 | /* gcc 4.0 and older doesn't have 'Z' constraint */ |
99 | static inline type name(const volatile type __iomem *addr) \ | 99 | #if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ == 0) |
100 | #define DEF_MMIO_IN_LE(name, size, insn) \ | ||
101 | static inline u##size name(const volatile u##size __iomem *addr) \ | ||
100 | { \ | 102 | { \ |
101 | type ret; \ | 103 | u##size ret; \ |
102 | __asm__ __volatile__("sync;" insn ";twi 0,%0,0;isync" \ | 104 | __asm__ __volatile__("sync;"#insn" %0,0,%1;twi 0,%0,0;isync" \ |
103 | : "=r" (ret) : "r" (addr), "m" (*addr) : "memory"); \ | 105 | : "=r" (ret) : "r" (addr), "m" (*addr) : "memory"); \ |
104 | return ret; \ | 106 | return ret; \ |
105 | } | 107 | } |
106 | 108 | ||
107 | #define DEF_MMIO_OUT(name, type, insn) \ | 109 | #define DEF_MMIO_OUT_LE(name, size, insn) \ |
108 | static inline void name(volatile type __iomem *addr, type val) \ | 110 | static inline void name(volatile u##size __iomem *addr, u##size val) \ |
109 | { \ | 111 | { \ |
110 | __asm__ __volatile__("sync;" insn \ | 112 | __asm__ __volatile__("sync;"#insn" %1,0,%2" \ |
111 | : "=m" (*addr) : "r" (val), "r" (addr) : "memory"); \ | 113 | : "=m" (*addr) : "r" (val), "r" (addr) : "memory"); \ |
112 | IO_SET_SYNC_FLAG(); \ | 114 | IO_SET_SYNC_FLAG(); \ |
113 | } | 115 | } |
116 | #else /* newer gcc */ | ||
117 | #define DEF_MMIO_IN_LE(name, size, insn) \ | ||
118 | static inline u##size name(const volatile u##size __iomem *addr) \ | ||
119 | { \ | ||
120 | u##size ret; \ | ||
121 | __asm__ __volatile__("sync;"#insn" %0,%y1;twi 0,%0,0;isync" \ | ||
122 | : "=r" (ret) : "Z" (*addr) : "memory"); \ | ||
123 | return ret; \ | ||
124 | } | ||
125 | |||
126 | #define DEF_MMIO_OUT_LE(name, size, insn) \ | ||
127 | static inline void name(volatile u##size __iomem *addr, u##size val) \ | ||
128 | { \ | ||
129 | __asm__ __volatile__("sync;"#insn" %1,%y0" \ | ||
130 | : "=Z" (*addr) : "r" (val) : "memory"); \ | ||
131 | IO_SET_SYNC_FLAG(); \ | ||
132 | } | ||
133 | #endif | ||
114 | 134 | ||
135 | #define DEF_MMIO_IN_BE(name, size, insn) \ | ||
136 | static inline u##size name(const volatile u##size __iomem *addr) \ | ||
137 | { \ | ||
138 | u##size ret; \ | ||
139 | __asm__ __volatile__("sync;"#insn"%U1%X1 %0,%1;twi 0,%0,0;isync"\ | ||
140 | : "=r" (ret) : "m" (*addr) : "memory"); \ | ||
141 | return ret; \ | ||
142 | } | ||
115 | 143 | ||
116 | #define DEF_MMIO_IN_BE(name, size, insn) \ | 144 | #define DEF_MMIO_OUT_BE(name, size, insn) \ |
117 | DEF_MMIO_IN(name, u##size, __stringify(insn)"%U2%X2 %0,%2") | 145 | static inline void name(volatile u##size __iomem *addr, u##size val) \ |
118 | #define DEF_MMIO_IN_LE(name, size, insn) \ | 146 | { \ |
119 | DEF_MMIO_IN(name, u##size, __stringify(insn)" %0,0,%1") | 147 | __asm__ __volatile__("sync;"#insn"%U0%X0 %1,%0" \ |
148 | : "=m" (*addr) : "r" (val) : "memory"); \ | ||
149 | IO_SET_SYNC_FLAG(); \ | ||
150 | } | ||
120 | 151 | ||
121 | #define DEF_MMIO_OUT_BE(name, size, insn) \ | ||
122 | DEF_MMIO_OUT(name, u##size, __stringify(insn)"%U0%X0 %1,%0") | ||
123 | #define DEF_MMIO_OUT_LE(name, size, insn) \ | ||
124 | DEF_MMIO_OUT(name, u##size, __stringify(insn)" %1,0,%2") | ||
125 | 152 | ||
126 | DEF_MMIO_IN_BE(in_8, 8, lbz); | 153 | DEF_MMIO_IN_BE(in_8, 8, lbz); |
127 | DEF_MMIO_IN_BE(in_be16, 16, lhz); | 154 | DEF_MMIO_IN_BE(in_be16, 16, lhz); |