aboutsummaryrefslogtreecommitdiffstats
path: root/include/asm-generic
diff options
context:
space:
mode:
authorThierry Reding <treding@nvidia.com>2014-07-04 07:07:57 -0400
committerThierry Reding <treding@nvidia.com>2014-11-10 09:59:22 -0500
commit9ab3a7a0d2b417773e8e8a880fc3a69f7fc1f57a (patch)
tree2be088f766848130e1a6f38d8ba7ef4c9486df81 /include/asm-generic
parent9216efafc52ff99e9351ef60de5fcafc2bc8adb6 (diff)
asm-generic/io.h: Implement generic {read,write}s*()
Currently driver writers need to use io{read,write}{8,16,32}_rep() when accessing FIFO registers portably. This is bad for two reasons: it is inconsistent with how other registers are accessed using the standard {read,write}{b,w,l}() functions, which can lead to confusion. On some architectures the io{read,write}*() functions also need to perform some extra checks to determine whether an address is memory-mapped or refers to I/O space. Drivers which can be expected to never use I/O can safely use the {read,write}s{b,w,l,q}(), just like they use their non-string variants and there's no need for these extra checks. This patch implements generic versions of readsb(), readsw(), readsl(), readsq(), writesb(), writesw(), writesl() and writesq(). Variants of these string functions for I/O accesses (ins*() and outs*() as well as ioread*_rep() and iowrite*_rep()) are now implemented in terms of the new functions. Going forward, {read,write}{,s}{b,w,l,q}() should be used consistently by drivers for devices that will only ever be memory-mapped and hence don't need to access I/O space, whereas io{read,write}{8,16,32}_rep() should be used by drivers for devices that can be either memory-mapped or I/O-mapped. Signed-off-by: Thierry Reding <treding@nvidia.com>
Diffstat (limited to 'include/asm-generic')
-rw-r--r--include/asm-generic/io.h271
1 files changed, 238 insertions, 33 deletions
diff --git a/include/asm-generic/io.h b/include/asm-generic/io.h
index fb62c621acf9..00483d769d86 100644
--- a/include/asm-generic/io.h
+++ b/include/asm-generic/io.h
@@ -174,96 +174,137 @@ static inline void writeq(u64 value, volatile void __iomem *addr)
174#endif 174#endif
175#endif /* CONFIG_64BIT */ 175#endif /* CONFIG_64BIT */
176 176
177#ifndef insb 177/*
178static inline void insb(unsigned long addr, void *buffer, int count) 178 * {read,write}s{b,w,l,q}() repeatedly access the same memory address in
179 * native endianness in 8-, 16-, 32- or 64-bit chunks (@count times).
180 */
181#ifndef readsb
182#define readsb readsb
183static inline void readsb(const volatile void __iomem *addr, void *buffer,
184 unsigned int count)
179{ 185{
180 if (count) { 186 if (count) {
181 u8 *buf = buffer; 187 u8 *buf = buffer;
188
182 do { 189 do {
183 u8 x = __raw_readb(addr + PCI_IOBASE); 190 u8 x = __raw_readb(addr);
184 *buf++ = x; 191 *buf++ = x;
185 } while (--count); 192 } while (--count);
186 } 193 }
187} 194}
188#endif 195#endif
189 196
190#ifndef insw 197#ifndef readsw
191static inline void insw(unsigned long addr, void *buffer, int count) 198#define readsw readsw
199static inline void readsw(const volatile void __iomem *addr, void *buffer,
200 unsigned int count)
192{ 201{
193 if (count) { 202 if (count) {
194 u16 *buf = buffer; 203 u16 *buf = buffer;
204
195 do { 205 do {
196 u16 x = __raw_readw(addr + PCI_IOBASE); 206 u16 x = __raw_readw(addr);
197 *buf++ = x; 207 *buf++ = x;
198 } while (--count); 208 } while (--count);
199 } 209 }
200} 210}
201#endif 211#endif
202 212
203#ifndef insl 213#ifndef readsl
204static inline void insl(unsigned long addr, void *buffer, int count) 214#define readsl readsl
215static inline void readsl(const volatile void __iomem *addr, void *buffer,
216 unsigned int count)
205{ 217{
206 if (count) { 218 if (count) {
207 u32 *buf = buffer; 219 u32 *buf = buffer;
220
208 do { 221 do {
209 u32 x = __raw_readl(addr + PCI_IOBASE); 222 u32 x = __raw_readl(addr);
210 *buf++ = x; 223 *buf++ = x;
211 } while (--count); 224 } while (--count);
212 } 225 }
213} 226}
214#endif 227#endif
215 228
216#ifndef outsb 229#ifdef CONFIG_64BIT
217static inline void outsb(unsigned long addr, const void *buffer, int count) 230#ifndef readsq
231#define readsq readsq
232static inline void readsq(const volatile void __iomem *addr, void *buffer,
233 unsigned int count)
234{
235 if (count) {
236 u64 *buf = buffer;
237
238 do {
239 u64 x = __raw_readq(addr);
240 *buf++ = x;
241 } while (--count);
242 }
243}
244#endif
245#endif /* CONFIG_64BIT */
246
247#ifndef writesb
248#define writesb writesb
249static inline void writesb(volatile void __iomem *addr, const void *buffer,
250 unsigned int count)
218{ 251{
219 if (count) { 252 if (count) {
220 const u8 *buf = buffer; 253 const u8 *buf = buffer;
254
221 do { 255 do {
222 __raw_writeb(*buf++, addr + PCI_IOBASE); 256 __raw_writeb(*buf++, addr);
223 } while (--count); 257 } while (--count);
224 } 258 }
225} 259}
226#endif 260#endif
227 261
228#ifndef outsw 262#ifndef writesw
229static inline void outsw(unsigned long addr, const void *buffer, int count) 263#define writesw writesw
264static inline void writesw(volatile void __iomem *addr, const void *buffer,
265 unsigned int count)
230{ 266{
231 if (count) { 267 if (count) {
232 const u16 *buf = buffer; 268 const u16 *buf = buffer;
269
233 do { 270 do {
234 __raw_writew(*buf++, addr + PCI_IOBASE); 271 __raw_writew(*buf++, addr);
235 } while (--count); 272 } while (--count);
236 } 273 }
237} 274}
238#endif 275#endif
239 276
240#ifndef outsl 277#ifndef writesl
241static inline void outsl(unsigned long addr, const void *buffer, int count) 278#define writesl writesl
279static inline void writesl(volatile void __iomem *addr, const void *buffer,
280 unsigned int count)
242{ 281{
243 if (count) { 282 if (count) {
244 const u32 *buf = buffer; 283 const u32 *buf = buffer;
284
245 do { 285 do {
246 __raw_writel(*buf++, addr + PCI_IOBASE); 286 __raw_writel(*buf++, addr);
247 } while (--count); 287 } while (--count);
248 } 288 }
249} 289}
250#endif 290#endif
251 291
252#ifndef CONFIG_GENERIC_IOMAP 292#ifdef CONFIG_64BIT
253#define ioread8_rep(p, dst, count) \ 293#ifndef writesq
254 insb((unsigned long) (p), (dst), (count)) 294#define writesq writesq
255#define ioread16_rep(p, dst, count) \ 295static inline void writesq(volatile void __iomem *addr, const void *buffer,
256 insw((unsigned long) (p), (dst), (count)) 296 unsigned int count)
257#define ioread32_rep(p, dst, count) \ 297{
258 insl((unsigned long) (p), (dst), (count)) 298 if (count) {
259 299 const u64 *buf = buffer;
260#define iowrite8_rep(p, src, count) \ 300
261 outsb((unsigned long) (p), (src), (count)) 301 do {
262#define iowrite16_rep(p, src, count) \ 302 __raw_writeq(*buf++, addr);
263 outsw((unsigned long) (p), (src), (count)) 303 } while (--count);
264#define iowrite32_rep(p, src, count) \ 304 }
265 outsl((unsigned long) (p), (src), (count)) 305}
266#endif /* CONFIG_GENERIC_IOMAP */ 306#endif
307#endif /* CONFIG_64BIT */
267 308
268#ifndef PCI_IOBASE 309#ifndef PCI_IOBASE
269#define PCI_IOBASE ((void __iomem *)0) 310#define PCI_IOBASE ((void __iomem *)0)
@@ -375,6 +416,113 @@ static inline void outl_p(u32 value, unsigned long addr)
375} 416}
376#endif 417#endif
377 418