root/arch/alpha/kernel/io.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ioread8
  2. ioread16
  3. ioread32
  4. iowrite8
  5. iowrite16
  6. iowrite32
  7. inb
  8. inw
  9. inl
  10. outb
  11. outw
  12. outl
  13. __raw_readb
  14. __raw_readw
  15. __raw_readl
  16. __raw_readq
  17. __raw_writeb
  18. __raw_writew
  19. __raw_writel
  20. __raw_writeq
  21. readb
  22. readw
  23. readl
  24. readq
  25. writeb
  26. writew
  27. writel
  28. writeq
  29. ioread8_rep
  30. insb
  31. ioread16_rep
  32. insw
  33. ioread32_rep
  34. insl
  35. iowrite8_rep
  36. outsb
  37. iowrite16_rep
  38. outsw
  39. iowrite32_rep
  40. outsl
  41. memcpy_fromio
  42. memcpy_toio
  43. _memset_c_io
  44. scr_memcpyw
  45. ioport_map
  46. ioport_unmap

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * Alpha IO and memory functions.
   4  */
   5 
   6 #include <linux/kernel.h>
   7 #include <linux/types.h>
   8 #include <linux/string.h>
   9 #include <linux/module.h>
  10 #include <asm/io.h>
  11 
  12 /* Out-of-line versions of the i/o routines that redirect into the 
  13    platform-specific version.  Note that "platform-specific" may mean
  14    "generic", which bumps through the machine vector.  */
  15 
  16 unsigned int
  17 ioread8(void __iomem *addr)
  18 {
  19         unsigned int ret = IO_CONCAT(__IO_PREFIX,ioread8)(addr);
  20         mb();
  21         return ret;
  22 }
  23 
  24 unsigned int ioread16(void __iomem *addr)
  25 {
  26         unsigned int ret = IO_CONCAT(__IO_PREFIX,ioread16)(addr);
  27         mb();
  28         return ret;
  29 }
  30 
  31 unsigned int ioread32(void __iomem *addr)
  32 {
  33         unsigned int ret = IO_CONCAT(__IO_PREFIX,ioread32)(addr);
  34         mb();
  35         return ret;
  36 }
  37 
  38 void iowrite8(u8 b, void __iomem *addr)
  39 {
  40         mb();
  41         IO_CONCAT(__IO_PREFIX,iowrite8)(b, addr);
  42 }
  43 
  44 void iowrite16(u16 b, void __iomem *addr)
  45 {
  46         mb();
  47         IO_CONCAT(__IO_PREFIX,iowrite16)(b, addr);
  48 }
  49 
  50 void iowrite32(u32 b, void __iomem *addr)
  51 {
  52         mb();
  53         IO_CONCAT(__IO_PREFIX,iowrite32)(b, addr);
  54 }
  55 
  56 EXPORT_SYMBOL(ioread8);
  57 EXPORT_SYMBOL(ioread16);
  58 EXPORT_SYMBOL(ioread32);
  59 EXPORT_SYMBOL(iowrite8);
  60 EXPORT_SYMBOL(iowrite16);
  61 EXPORT_SYMBOL(iowrite32);
  62 
  63 u8 inb(unsigned long port)
  64 {
  65         return ioread8(ioport_map(port, 1));
  66 }
  67 
  68 u16 inw(unsigned long port)
  69 {
  70         return ioread16(ioport_map(port, 2));
  71 }
  72 
  73 u32 inl(unsigned long port)
  74 {
  75         return ioread32(ioport_map(port, 4));
  76 }
  77 
  78 void outb(u8 b, unsigned long port)
  79 {
  80         iowrite8(b, ioport_map(port, 1));
  81 }
  82 
  83 void outw(u16 b, unsigned long port)
  84 {
  85         iowrite16(b, ioport_map(port, 2));
  86 }
  87 
  88 void outl(u32 b, unsigned long port)
  89 {
  90         iowrite32(b, ioport_map(port, 4));
  91 }
  92 
  93 EXPORT_SYMBOL(inb);
  94 EXPORT_SYMBOL(inw);
  95 EXPORT_SYMBOL(inl);
  96 EXPORT_SYMBOL(outb);
  97 EXPORT_SYMBOL(outw);
  98 EXPORT_SYMBOL(outl);
  99 
 100 u8 __raw_readb(const volatile void __iomem *addr)
 101 {
 102         return IO_CONCAT(__IO_PREFIX,readb)(addr);
 103 }
 104 
 105 u16 __raw_readw(const volatile void __iomem *addr)
 106 {
 107         return IO_CONCAT(__IO_PREFIX,readw)(addr);
 108 }
 109 
 110 u32 __raw_readl(const volatile void __iomem *addr)
 111 {
 112         return IO_CONCAT(__IO_PREFIX,readl)(addr);
 113 }
 114 
 115 u64 __raw_readq(const volatile void __iomem *addr)
 116 {
 117         return IO_CONCAT(__IO_PREFIX,readq)(addr);
 118 }
 119 
 120 void __raw_writeb(u8 b, volatile void __iomem *addr)
 121 {
 122         IO_CONCAT(__IO_PREFIX,writeb)(b, addr);
 123 }
 124 
 125 void __raw_writew(u16 b, volatile void __iomem *addr)
 126 {
 127         IO_CONCAT(__IO_PREFIX,writew)(b, addr);
 128 }
 129 
 130 void __raw_writel(u32 b, volatile void __iomem *addr)
 131 {
 132         IO_CONCAT(__IO_PREFIX,writel)(b, addr);
 133 }
 134 
 135 void __raw_writeq(u64 b, volatile void __iomem *addr)
 136 {
 137         IO_CONCAT(__IO_PREFIX,writeq)(b, addr);
 138 }
 139 
 140 EXPORT_SYMBOL(__raw_readb); 
 141 EXPORT_SYMBOL(__raw_readw); 
 142 EXPORT_SYMBOL(__raw_readl); 
 143 EXPORT_SYMBOL(__raw_readq); 
 144 EXPORT_SYMBOL(__raw_writeb); 
 145 EXPORT_SYMBOL(__raw_writew); 
 146 EXPORT_SYMBOL(__raw_writel); 
 147 EXPORT_SYMBOL(__raw_writeq); 
 148 
 149 u8 readb(const volatile void __iomem *addr)
 150 {
 151         u8 ret = __raw_readb(addr);
 152         mb();
 153         return ret;
 154 }
 155 
 156 u16 readw(const volatile void __iomem *addr)
 157 {
 158         u16 ret = __raw_readw(addr);
 159         mb();
 160         return ret;
 161 }
 162 
 163 u32 readl(const volatile void __iomem *addr)
 164 {
 165         u32 ret = __raw_readl(addr);
 166         mb();
 167         return ret;
 168 }
 169 
 170 u64 readq(const volatile void __iomem *addr)
 171 {
 172         u64 ret = __raw_readq(addr);
 173         mb();
 174         return ret;
 175 }
 176 
 177 void writeb(u8 b, volatile void __iomem *addr)
 178 {
 179         mb();
 180         __raw_writeb(b, addr);
 181 }
 182 
 183 void writew(u16 b, volatile void __iomem *addr)
 184 {
 185         mb();
 186         __raw_writew(b, addr);
 187 }
 188 
 189 void writel(u32 b, volatile void __iomem *addr)
 190 {
 191         mb();
 192         __raw_writel(b, addr);
 193 }
 194 
 195 void writeq(u64 b, volatile void __iomem *addr)
 196 {
 197         mb();
 198         __raw_writeq(b, addr);
 199 }
 200 
 201 EXPORT_SYMBOL(readb);
 202 EXPORT_SYMBOL(readw);
 203 EXPORT_SYMBOL(readl);
 204 EXPORT_SYMBOL(readq);
 205 EXPORT_SYMBOL(writeb);
 206 EXPORT_SYMBOL(writew);
 207 EXPORT_SYMBOL(writel);
 208 EXPORT_SYMBOL(writeq);
 209 
 210 
 211 /*
 212  * Read COUNT 8-bit bytes from port PORT into memory starting at SRC.
 213  */
 214 void ioread8_rep(void __iomem *port, void *dst, unsigned long count)
 215 {
 216         while ((unsigned long)dst & 0x3) {
 217                 if (!count)
 218                         return;
 219                 count--;
 220                 *(unsigned char *)dst = ioread8(port);
 221                 dst += 1;
 222         }
 223 
 224         while (count >= 4) {
 225                 unsigned int w;
 226                 count -= 4;
 227                 w = ioread8(port);
 228                 w |= ioread8(port) << 8;
 229                 w |= ioread8(port) << 16;
 230                 w |= ioread8(port) << 24;
 231                 *(unsigned int *)dst = w;
 232                 dst += 4;
 233         }
 234 
 235         while (count) {
 236                 --count;
 237                 *(unsigned char *)dst = ioread8(port);
 238                 dst += 1;
 239         }
 240 }
 241 
 242 void insb(unsigned long port, void *dst, unsigned long count)
 243 {
 244         ioread8_rep(ioport_map(port, 1), dst, count);
 245 }
 246 
 247 EXPORT_SYMBOL(ioread8_rep);
 248 EXPORT_SYMBOL(insb);
 249 
 250 /*
 251  * Read COUNT 16-bit words from port PORT into memory starting at
 252  * SRC.  SRC must be at least short aligned.  This is used by the
 253  * IDE driver to read disk sectors.  Performance is important, but
 254  * the interfaces seems to be slow: just using the inlined version
 255  * of the inw() breaks things.
 256  */
 257 void ioread16_rep(void __iomem *port, void *dst, unsigned long count)
 258 {
 259         if (unlikely((unsigned long)dst & 0x3)) {
 260                 if (!count)
 261                         return;
 262                 BUG_ON((unsigned long)dst & 0x1);
 263                 count--;
 264                 *(unsigned short *)dst = ioread16(port);
 265                 dst += 2;
 266         }
 267 
 268         while (count >= 2) {
 269                 unsigned int w;
 270                 count -= 2;
 271                 w = ioread16(port);
 272                 w |= ioread16(port) << 16;
 273                 *(unsigned int *)dst = w;
 274                 dst += 4;
 275         }
 276 
 277         if (count) {
 278                 *(unsigned short*)dst = ioread16(port);
 279         }
 280 }
 281 
 282 void insw(unsigned long port, void *dst, unsigned long count)
 283 {
 284         ioread16_rep(ioport_map(port, 2), dst, count);
 285 }
 286 
 287 EXPORT_SYMBOL(ioread16_rep);
 288 EXPORT_SYMBOL(insw);
 289 
 290 
 291 /*
 292  * Read COUNT 32-bit words from port PORT into memory starting at
 293  * SRC. Now works with any alignment in SRC. Performance is important,
 294  * but the interfaces seems to be slow: just using the inlined version
 295  * of the inl() breaks things.
 296  */
 297 void ioread32_rep(void __iomem *port, void *dst, unsigned long count)
 298 {
 299         if (unlikely((unsigned long)dst & 0x3)) {
 300                 while (count--) {
 301                         struct S { int x __attribute__((packed)); };
 302                         ((struct S *)dst)->x = ioread32(port);
 303                         dst += 4;
 304                 }
 305         } else {
 306                 /* Buffer 32-bit aligned.  */
 307                 while (count--) {
 308                         *(unsigned int *)dst = ioread32(port);
 309                         dst += 4;
 310                 }
 311         }
 312 }
 313 
 314 void insl(unsigned long port, void *dst, unsigned long count)
 315 {
 316         ioread32_rep(ioport_map(port, 4), dst, count);
 317 }
 318 
 319 EXPORT_SYMBOL(ioread32_rep);
 320 EXPORT_SYMBOL(insl);
 321 
 322 
 323 /*
 324  * Like insb but in the opposite direction.
 325  * Don't worry as much about doing aligned memory transfers:
 326  * doing byte reads the "slow" way isn't nearly as slow as
 327  * doing byte writes the slow way (no r-m-w cycle).
 328  */
 329 void iowrite8_rep(void __iomem *port, const void *xsrc, unsigned long count)
 330 {
 331         const unsigned char *src = xsrc;
 332         while (count--)
 333                 iowrite8(*src++, port);
 334 }
 335 
 336 void outsb(unsigned long port, const void *src, unsigned long count)
 337 {
 338         iowrite8_rep(ioport_map(port, 1), src, count);
 339 }
 340 
 341 EXPORT_SYMBOL(iowrite8_rep);
 342 EXPORT_SYMBOL(outsb);
 343 
 344 
 345 /*
 346  * Like insw but in the opposite direction.  This is used by the IDE
 347  * driver to write disk sectors.  Performance is important, but the
 348  * interfaces seems to be slow: just using the inlined version of the
 349  * outw() breaks things.
 350  */
 351 void iowrite16_rep(void __iomem *port, const void *src, unsigned long count)
 352 {
 353         if (unlikely((unsigned long)src & 0x3)) {
 354                 if (!count)
 355                         return;
 356                 BUG_ON((unsigned long)src & 0x1);
 357                 iowrite16(*(unsigned short *)src, port);
 358                 src += 2;
 359                 --count;
 360         }
 361 
 362         while (count >= 2) {
 363                 unsigned int w;
 364                 count -= 2;
 365                 w = *(unsigned int *)src;
 366                 src += 4;
 367                 iowrite16(w >>  0, port);
 368                 iowrite16(w >> 16, port);
 369         }
 370 
 371         if (count) {
 372                 iowrite16(*(unsigned short *)src, port);
 373         }
 374 }
 375 
 376 void outsw(unsigned long port, const void *src, unsigned long count)
 377 {
 378         iowrite16_rep(ioport_map(port, 2), src, count);
 379 }
 380 
 381 EXPORT_SYMBOL(iowrite16_rep);
 382 EXPORT_SYMBOL(outsw);
 383 
 384 
 385 /*
 386  * Like insl but in the opposite direction.  This is used by the IDE
 387  * driver to write disk sectors.  Works with any alignment in SRC.
 388  * Performance is important, but the interfaces seems to be slow:
 389  * just using the inlined version of the outl() breaks things.
 390  */
 391 void iowrite32_rep(void __iomem *port, const void *src, unsigned long count)
 392 {
 393         if (unlikely((unsigned long)src & 0x3)) {
 394                 while (count--) {
 395                         struct S { int x __attribute__((packed)); };
 396                         iowrite32(((struct S *)src)->x, port);
 397                         src += 4;
 398                 }
 399         } else {
 400                 /* Buffer 32-bit aligned.  */
 401                 while (count--) {
 402                         iowrite32(*(unsigned int *)src, port);
 403                         src += 4;
 404                 }
 405         }
 406 }
 407 
 408 void outsl(unsigned long port, const void *src, unsigned long count)
 409 {
 410         iowrite32_rep(ioport_map(port, 4), src, count);
 411 }
 412 
 413 EXPORT_SYMBOL(iowrite32_rep);
 414 EXPORT_SYMBOL(outsl);
 415 
 416 
 417 /*
 418  * Copy data from IO memory space to "real" memory space.
 419  * This needs to be optimized.
 420  */
 421 void memcpy_fromio(void *to, const volatile void __iomem *from, long count)
 422 {
 423         /* Optimize co-aligned transfers.  Everything else gets handled
 424            a byte at a time. */
 425 
 426         if (count >= 8 && ((u64)to & 7) == ((u64)from & 7)) {
 427                 count -= 8;
 428                 do {
 429                         *(u64 *)to = __raw_readq(from);
 430                         count -= 8;
 431                         to += 8;
 432                         from += 8;
 433                 } while (count >= 0);
 434                 count += 8;
 435         }
 436 
 437         if (count >= 4 && ((u64)to & 3) == ((u64)from & 3)) {
 438                 count -= 4;
 439                 do {
 440                         *(u32 *)to = __raw_readl(from);
 441                         count -= 4;
 442                         to += 4;
 443                         from += 4;
 444                 } while (count >= 0);
 445                 count += 4;
 446         }
 447 
 448         if (count >= 2 && ((u64)to & 1) == ((u64)from & 1)) {
 449                 count -= 2;
 450                 do {
 451                         *(u16 *)to = __raw_readw(from);
 452                         count -= 2;
 453                         to += 2;
 454                         from += 2;
 455                 } while (count >= 0);
 456                 count += 2;
 457         }
 458 
 459         while (count > 0) {
 460                 *(u8 *) to = __raw_readb(from);
 461                 count--;
 462                 to++;
 463                 from++;
 464         }
 465         mb();
 466 }
 467 
 468 EXPORT_SYMBOL(memcpy_fromio);
 469 
 470 
 471 /*
 472  * Copy data from "real" memory space to IO memory space.
 473  * This needs to be optimized.
 474  */
 475 void memcpy_toio(volatile void __iomem *to, const void *from, long count)
 476 {
 477         /* Optimize co-aligned transfers.  Everything else gets handled
 478            a byte at a time. */
 479         /* FIXME -- align FROM.  */
 480 
 481         if (count >= 8 && ((u64)to & 7) == ((u64)from & 7)) {
 482                 count -= 8;
 483                 do {
 484                         __raw_writeq(*(const u64 *)from, to);
 485                         count -= 8;
 486                         to += 8;
 487                         from += 8;
 488                 } while (count >= 0);
 489                 count += 8;
 490         }
 491 
 492         if (count >= 4 && ((u64)to & 3) == ((u64)from & 3)) {
 493                 count -= 4;
 494                 do {
 495                         __raw_writel(*(const u32 *)from, to);
 496                         count -= 4;
 497                         to += 4;
 498                         from += 4;
 499                 } while (count >= 0);
 500                 count += 4;
 501         }
 502 
 503         if (count >= 2 && ((u64)to & 1) == ((u64)from & 1)) {
 504                 count -= 2;
 505                 do {
 506                         __raw_writew(*(const u16 *)from, to);
 507                         count -= 2;
 508                         to += 2;
 509                         from += 2;
 510                 } while (count >= 0);
 511                 count += 2;
 512         }
 513 
 514         while (count > 0) {
 515                 __raw_writeb(*(const u8 *) from, to);
 516                 count--;
 517                 to++;
 518                 from++;
 519         }
 520         mb();
 521 }
 522 
 523 EXPORT_SYMBOL(memcpy_toio);
 524 
 525 
 526 /*
 527  * "memset" on IO memory space.
 528  */
 529 void _memset_c_io(volatile void __iomem *to, unsigned long c, long count)
 530 {
 531         /* Handle any initial odd byte */
 532         if (count > 0 && ((u64)to & 1)) {
 533                 __raw_writeb(c, to);
 534                 to++;
 535                 count--;
 536         }
 537 
 538         /* Handle any initial odd halfword */
 539         if (count >= 2 && ((u64)to & 2)) {
 540                 __raw_writew(c, to);
 541                 to += 2;
 542                 count -= 2;
 543         }
 544 
 545         /* Handle any initial odd word */
 546         if (count >= 4 && ((u64)to & 4)) {
 547                 __raw_writel(c, to);
 548                 to += 4;
 549                 count -= 4;
 550         }
 551 
 552         /* Handle all full-sized quadwords: we're aligned
 553            (or have a small count) */
 554         count -= 8;
 555         if (count >= 0) {
 556                 do {
 557                         __raw_writeq(c, to);
 558                         to += 8;
 559                         count -= 8;
 560                 } while (count >= 0);
 561         }
 562         count += 8;
 563 
 564         /* The tail is word-aligned if we still have count >= 4 */
 565         if (count >= 4) {
 566                 __raw_writel(c, to);
 567                 to += 4;
 568                 count -= 4;
 569         }
 570 
 571         /* The tail is half-word aligned if we have count >= 2 */
 572         if (count >= 2) {
 573                 __raw_writew(c, to);
 574                 to += 2;
 575                 count -= 2;
 576         }
 577 
 578         /* And finally, one last byte.. */
 579         if (count) {
 580                 __raw_writeb(c, to);
 581         }
 582         mb();
 583 }
 584 
 585 EXPORT_SYMBOL(_memset_c_io);
 586 
 587 /* A version of memcpy used by the vga console routines to move data around
 588    arbitrarily between screen and main memory.  */
 589 
 590 void
 591 scr_memcpyw(u16 *d, const u16 *s, unsigned int count)
 592 {
 593         const u16 __iomem *ios = (const u16 __iomem *) s;
 594         u16 __iomem *iod = (u16 __iomem *) d;
 595         int s_isio = __is_ioaddr(s);
 596         int d_isio = __is_ioaddr(d);
 597 
 598         if (s_isio) {
 599                 if (d_isio) {
 600                         /* FIXME: Should handle unaligned ops and
 601                            operation widening.  */
 602 
 603                         count /= 2;
 604                         while (count--) {
 605                                 u16 tmp = __raw_readw(ios++);
 606                                 __raw_writew(tmp, iod++);
 607                         }
 608                 }
 609                 else
 610                         memcpy_fromio(d, ios, count);
 611         } else {
 612                 if (d_isio)
 613                         memcpy_toio(iod, s, count);
 614                 else
 615                         memcpy(d, s, count);
 616         }
 617 }
 618 
 619 EXPORT_SYMBOL(scr_memcpyw);
 620 
 621 void __iomem *ioport_map(unsigned long port, unsigned int size)
 622 {
 623         return IO_CONCAT(__IO_PREFIX,ioportmap) (port);
 624 }
 625 
 626 void ioport_unmap(void __iomem *addr)
 627 {
 628 }
 629 
 630 EXPORT_SYMBOL(ioport_map);
 631 EXPORT_SYMBOL(ioport_unmap);

/* [<][>][^][v][top][bottom][index][help] */