aboutsummaryrefslogtreecommitdiffstats
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
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>
-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
419/*
420 * {in,out}s{b,w,l}{,_p}() are variants of the above that repeatedly access a
421 * single I/O port multiple times.
422 */
423
424#ifndef insb
425#define insb insb
426static inline void insb(unsigned long addr, void *buffer, unsigned int count)
427{
428 readsb(PCI_IOBASE + addr, buffer, count);
429}
430#endif
431
432#ifndef insw
433#define insw insw
434static inline void insw(unsigned long addr, void *buffer, unsigned int count)
435{
436 readsw(PCI_IOBASE + addr, buffer, count);
437}
438#endif
439
440#ifndef insl
441#define insl insl
442static inline void insl(unsigned long addr, void *buffer, unsigned int count)
443{
444 readsl(PCI_IOBASE + addr, buffer, count);
445}
446#endif
447
448#ifndef outsb
449#define outsb outsb
450static inline void outsb(unsigned long addr, const void *buffer,
451 unsigned int count)
452{
453 writesb(PCI_IOBASE + addr, buffer, count);
454}
455#endif
456
457#ifndef outsw
458#define outsw outsw
459static inline void outsw(unsigned long addr, const void *buffer,
460 unsigned int count)
461{
462 writesw(PCI_IOBASE + addr, buffer, count);
463}
464#endif
465
466#ifndef outsl
467#define outsl outsl
468static inline void outsl(unsigned long addr, const void *buffer,
469 unsigned int count)
470{
471 writesl(PCI_IOBASE + addr, buffer, count);
472}
473#endif
474
475#ifndef insb_p
476#define insb_p insb_p
477static inline void insb_p(unsigned long addr, void *buffer, unsigned int count)
478{
479 insb(addr, buffer, count);
480}
481#endif
482
483#ifndef insw_p
484#define insw_p insw_p
485static inline void insw_p(unsigned long addr, void *buffer, unsigned int count)
486{
487 insw(addr, buffer, count);
488}
489#endif
490
491#ifndef insl_p
492#define insl_p insl_p
493static inline void insl_p(unsigned long addr, void *buffer, unsigned int count)
494{
495 insl(addr, buffer, count);
496}
497#endif
498
499#ifndef outsb_p
500#define outsb_p outsb_p
501static inline void outsb_p(unsigned long addr, const void *buffer,
502 unsigned int count)
503{
504 outsb(addr, buffer, count);
505}
506#endif
507
508#ifndef outsw_p
509#define outsw_p outsw_p
510static inline void outsw_p(unsigned long addr, const void *buffer,
511 unsigned int count)
512{
513 outsw(addr, buffer, count);
514}
515#endif
516
517#ifndef outsl_p
518#define outsl_p outsl_p
519static inline void outsl_p(unsigned long addr, const void *buffer,
520 unsigned int count)
521{
522 outsl(addr, buffer, count);
523}
524#endif
525
378#ifndef CONFIG_GENERIC_IOMAP 526#ifndef CONFIG_GENERIC_IOMAP
379#ifndef ioread8 527#ifndef ioread8
380#define ioread8 ioread8 528#define ioread8 ioread8
@@ -455,6 +603,63 @@ static inline void iowrite32be(u32 value, volatile void __iomem *addr)
455 __raw_writel(__cpu_to_be32(value), addr); 603 __raw_writel(__cpu_to_be32(value), addr);
456} 604}
457#endif 605#endif
606
607#ifndef ioread8_rep
608#define ioread8_rep ioread8_rep
609static inline void ioread8_rep(const volatile void __iomem *addr, void *buffer,
610 unsigned int count)
611{
612 readsb(addr, buffer, count);
613}
614#endif
615
616#ifndef ioread16_rep
617#define ioread16_rep ioread16_rep
618static inline void ioread16_rep(const volatile void __iomem *addr,
619 void *buffer, unsigned int count)
620{
621 readsw(addr, buffer, count);
622}
623#endif
624
625#ifndef ioread32_rep
626#define ioread32_rep ioread32_rep
627static inline void ioread32_rep(const volatile void __iomem *addr,
628 void *buffer, unsigned int count)
629{
630 readsl(addr, buffer, count);
631}
632#endif
633
634#ifndef iowrite8_rep
635#define iowrite8_rep iowrite8_rep
636static inline void iowrite8_rep(volatile void __iomem *addr,
637 const void *buffer,
638 unsigned int count)
639{
640 writesb(addr, buffer, count);
641}
642#endif
643
644#ifndef iowrite16_rep
645#define iowrite16_rep iowrite16_rep
646static inline void iowrite16_rep(volatile void __iomem *addr,
647 const void *buffer,
648 unsigned int count)
649{
650 writesw(addr, buffer, count);
651}
652#endif
653
654#ifndef iowrite32_rep
655#define iowrite32_rep iowrite32_rep
656static inline void iowrite32_rep(volatile void __iomem *addr,
657 const void *buffer,
658 unsigned int count)
659{
660 writesl(addr, buffer, count);
661}
662#endif
458#endif /* CONFIG_GENERIC_IOMAP */ 663#endif /* CONFIG_GENERIC_IOMAP */
459 664
460#ifdef __KERNEL__ 665#ifdef __KERNEL__