diff options
author | Sinan Kaya <okaya@codeaurora.org> | 2018-04-05 09:09:10 -0400 |
---|---|---|
committer | Arnd Bergmann <arnd@arndb.de> | 2018-04-06 06:01:43 -0400 |
commit | 032d59e1cde9dd71bb5918e1f6529776623ee86b (patch) | |
tree | 4d66120ac6a1d2e4e34545fe68c19d1dd48ddde7 | |
parent | 64e2c6738b4d49d69d697b5887f72ad07c206ab3 (diff) |
io: define stronger ordering for the default readX() implementation
The default implementation of mapping readX() to __raw_readX() is wrong.
readX() has stronger ordering semantics. Compiler is allowed to reorder
__raw_readX() against the memory accesses following register read.
Use the previously defined __io_ar() and __io_br() macros to harden
code generation according to architecture support.
Signed-off-by: Sinan Kaya <okaya@codeaurora.org>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
-rw-r--r-- | include/asm-generic/io.h | 28 |
1 files changed, 24 insertions, 4 deletions
diff --git a/include/asm-generic/io.h b/include/asm-generic/io.h index 570433b34180..d27e8af9dd5a 100644 --- a/include/asm-generic/io.h +++ b/include/asm-generic/io.h | |||
@@ -154,7 +154,12 @@ static inline void __raw_writeq(u64 value, volatile void __iomem *addr) | |||
154 | #define readb readb | 154 | #define readb readb |
155 | static inline u8 readb(const volatile void __iomem *addr) | 155 | static inline u8 readb(const volatile void __iomem *addr) |
156 | { | 156 | { |
157 | return __raw_readb(addr); | 157 | u8 val; |
158 | |||
159 | __io_br(); | ||
160 | val = __raw_readb(addr); | ||
161 | __io_ar(); | ||
162 | return val; | ||
158 | } | 163 | } |
159 | #endif | 164 | #endif |
160 | 165 | ||
@@ -162,7 +167,12 @@ static inline u8 readb(const volatile void __iomem *addr) | |||
162 | #define readw readw | 167 | #define readw readw |
163 | static inline u16 readw(const volatile void __iomem *addr) | 168 | static inline u16 readw(const volatile void __iomem *addr) |
164 | { | 169 | { |
165 | return __le16_to_cpu(__raw_readw(addr)); | 170 | u16 val; |
171 | |||
172 | __io_br(); | ||
173 | val = __le16_to_cpu(__raw_readw(addr)); | ||
174 | __io_ar(); | ||
175 | return val; | ||
166 | } | 176 | } |
167 | #endif | 177 | #endif |
168 | 178 | ||
@@ -170,7 +180,12 @@ static inline u16 readw(const volatile void __iomem *addr) | |||
170 | #define readl readl | 180 | #define readl readl |
171 | static inline u32 readl(const volatile void __iomem *addr) | 181 | static inline u32 readl(const volatile void __iomem *addr) |
172 | { | 182 | { |
173 | return __le32_to_cpu(__raw_readl(addr)); | 183 | u32 val; |
184 | |||
185 | __io_br(); | ||
186 | val = __le32_to_cpu(__raw_readl(addr)); | ||
187 | __io_ar(); | ||
188 | return val; | ||
174 | } | 189 | } |
175 | #endif | 190 | #endif |
176 | 191 | ||
@@ -179,7 +194,12 @@ static inline u32 readl(const volatile void __iomem *addr) | |||
179 | #define readq readq | 194 | #define readq readq |
180 | static inline u64 readq(const volatile void __iomem *addr) | 195 | static inline u64 readq(const volatile void __iomem *addr) |
181 | { | 196 | { |
182 | return __le64_to_cpu(__raw_readq(addr)); | 197 | u64 val; |
198 | |||
199 | __io_br(); | ||
200 | val = __le64_to_cpu(__raw_readq(addr)); | ||
201 | __io_ar(); | ||
202 | return val; | ||
183 | } | 203 | } |
184 | #endif | 204 | #endif |
185 | #endif /* CONFIG_64BIT */ | 205 | #endif /* CONFIG_64BIT */ |