1// SPDX-License-Identifier: GPL-2.0 2/* 3 * iomap.c - Implement iomap interface for PA-RISC 4 * Copyright (c) 2004 Matthew Wilcox 5 */ 6 7#include <linux/ioport.h> 8#include <linux/pci.h> 9#include <linux/export.h> 10#include <asm/io.h> 11 12/* 13 * The iomap space on 32-bit PA-RISC is intended to look like this: 14 * 00000000-7fffffff virtual mapped IO 15 * 80000000-8fffffff ISA/EISA port space that can't be virtually mapped 16 * 90000000-9fffffff Dino port space 17 * a0000000-afffffff Astro port space 18 * b0000000-bfffffff PAT port space 19 * c0000000-cfffffff non-swapped memory IO 20 * f0000000-ffffffff legacy IO memory pointers 21 * 22 * For the moment, here's what it looks like: 23 * 80000000-8fffffff All ISA/EISA port space 24 * f0000000-ffffffff legacy IO memory pointers 25 * 26 * On 64-bit, everything is extended, so: 27 * 8000000000000000-8fffffffffffffff All ISA/EISA port space 28 * f000000000000000-ffffffffffffffff legacy IO memory pointers 29 */ 30 31/* 32 * Technically, this should be 'if (VMALLOC_START < addr < VMALLOC_END), 33 * but that's slow and we know it'll be within the first 2GB. 34 */ 35#ifdef CONFIG_64BIT 36#define INDIRECT_ADDR(addr) (((unsigned long)(addr) & 1UL<<63) != 0) 37#define ADDR_TO_REGION(addr) (((unsigned long)addr >> 60) & 7) 38#define IOPORT_MAP_BASE (8UL << 60) 39#else 40#define INDIRECT_ADDR(addr) (((unsigned long)(addr) & 1UL<<31) != 0) 41#define ADDR_TO_REGION(addr) (((unsigned long)addr >> 28) & 7) 42#define IOPORT_MAP_BASE (8UL << 28) 43#endif 44 45struct iomap_ops { 46 unsigned int (*read8)(const void __iomem *); 47 unsigned int (*read16)(const void __iomem *); 48 unsigned int (*read16be)(const void __iomem *); 49 unsigned int (*read32)(const void __iomem *); 50 unsigned int (*read32be)(const void __iomem *); 51#ifdef CONFIG_64BIT 52 u64 (*read64)(const void __iomem *); 53 u64 (*read64be)(const void __iomem *); 54#endif 55 void (*write8)(u8, void __iomem *); 56 void (*write16)(u16, void __iomem *); 57 void (*write16be)(u16, void __iomem *); 58 void (*write32)(u32, void __iomem *); 59 void (*write32be)(u32, void __iomem *); 60#ifdef CONFIG_64BIT 61 void (*write64)(u64, void __iomem *); 62 void (*write64be)(u64, void __iomem *); 63#endif 64 void (*read8r)(const void __iomem *, void *, unsigned long); 65 void (*read16r)(const void __iomem *, void *, unsigned long); 66 void (*read32r)(const void __iomem *, void *, unsigned long); 67 void (*write8r)(void __iomem *, const void *, unsigned long); 68 void (*write16r)(void __iomem *, const void *, unsigned long); 69 void (*write32r)(void __iomem *, const void *, unsigned long); 70}; 71 72/* Generic ioport ops. To be replaced later by specific dino/elroy/wax code */ 73 74#define ADDR2PORT(addr) ((unsigned long __force)(addr) & 0xffffff) 75 76static unsigned int ioport_read8(const void __iomem *addr) 77{ 78 return inb(ADDR2PORT(addr)); 79} 80 81static unsigned int ioport_read16(const void __iomem *addr) 82{ 83 return inw(ADDR2PORT(addr)); 84} 85 86static unsigned int ioport_read32(const void __iomem *addr) 87{ 88 return inl(ADDR2PORT(addr)); 89} 90 91static void ioport_write8(u8 datum, void __iomem *addr) 92{ 93 outb(datum, ADDR2PORT(addr)); 94} 95 96static void ioport_write16(u16 datum, void __iomem *addr) 97{ 98 outw(datum, ADDR2PORT(addr)); 99} 100 101static void ioport_write32(u32 datum, void __iomem *addr) 102{ 103 outl(datum, ADDR2PORT(addr)); 104} 105 106static void ioport_read8r(const void __iomem *addr, void *dst, unsigned long count) 107{ 108 insb(ADDR2PORT(addr), dst, count); 109} 110 111static void ioport_read16r(const void __iomem *addr, void *dst, unsigned long count) 112{ 113 insw(ADDR2PORT(addr), dst, count); 114} 115 116static void ioport_read32r(const void __iomem *addr, void *dst, unsigned long count) 117{ 118 insl(ADDR2PORT(addr), dst, count); 119} 120 121static void ioport_write8r(void __iomem *addr, const void *s, unsigned long n) 122{ 123 outsb(ADDR2PORT(addr), s, n); 124} 125 126static void ioport_write16r(void __iomem *addr, const void *s, unsigned long n) 127{ 128 outsw(ADDR2PORT(addr), s, n); 129} 130 131static void ioport_write32r(void __iomem *addr, const void *s, unsigned long n) 132{ 133 outsl(ADDR2PORT(addr), s, n); 134} 135 136static const struct iomap_ops ioport_ops = { 137 .read8 = ioport_read8, 138 .read16 = ioport_read16, 139 .read16be = ioport_read16, 140 .read32 = ioport_read32, 141 .read32be = ioport_read32, 142 .write8 = ioport_write8, 143 .write16 = ioport_write16, 144 .write16be = ioport_write16, 145 .write32 = ioport_write32, 146 .write32be = ioport_write32, 147 .read8r = ioport_read8r, 148 .read16r = ioport_read16r, 149 .read32r = ioport_read32r, 150 .write8r = ioport_write8r, 151 .write16r = ioport_write16r, 152 .write32r = ioport_write32r, 153}; 154 155/* Legacy I/O memory ops */ 156 157static unsigned int iomem_read8(const void __iomem *addr) 158{ 159 return readb(addr); 160} 161 162static unsigned int iomem_read16(const void __iomem *addr) 163{ 164 return readw(addr); 165} 166 167static unsigned int iomem_read16be(const void __iomem *addr) 168{ 169 return __raw_readw(addr); 170} 171 172static unsigned int iomem_read32(const void __iomem *addr) 173{ 174 return readl(addr); 175} 176 177static unsigned int iomem_read32be(const void __iomem *addr) 178{ 179 return __raw_readl(addr); 180} 181 182#ifdef CONFIG_64BIT 183static u64 iomem_read64(const void __iomem *addr) 184{ 185 return readq(addr); 186} 187 188static u64 iomem_read64be(const void __iomem *addr) 189{ 190 return __raw_readq(addr); 191} 192#endif 193 194static void iomem_write8(u8 datum, void __iomem *addr) 195{ 196 writeb(datum, addr); 197} 198 199static void iomem_write16(u16 datum, void __iomem *addr) 200{ 201 writew(datum, addr); 202} 203 204static void iomem_write16be(u16 datum, void __iomem *addr) 205{ 206 __raw_writew(datum, addr); 207} 208 209static void iomem_write32(u32 datum, void __iomem *addr) 210{ 211 writel(datum, addr); 212} 213 214static void iomem_write32be(u32 datum, void __iomem *addr) 215{ 216 __raw_writel(datum, addr); 217} 218 219#ifdef CONFIG_64BIT 220static void iomem_write64(u64 datum, void __iomem *addr) 221{ 222 writeq(datum, addr); 223} 224 225static void iomem_write64be(u64 datum, void __iomem *addr) 226{ 227 __raw_writeq(datum, addr); 228} 229#endif 230 231static void iomem_read8r(const void __iomem *addr, void *dst, unsigned long count) 232{ 233 while (count--) { 234 *(u8 *)dst = __raw_readb(addr); 235 dst++; 236 } 237} 238 239static void iomem_read16r(const void __iomem *addr, void *dst, unsigned long count) 240{ 241 while (count--) { 242 *(u16 *)dst = __raw_readw(addr); 243 dst += 2; 244 } 245} 246 247static void iomem_read32r(const void __iomem *addr, void *dst, unsigned long count) 248{ 249 while (count--) { 250 *(u32 *)dst = __raw_readl(addr); 251 dst += 4; 252 } 253} 254 255static void iomem_write8r(void __iomem *addr, const void *s, unsigned long n) 256{ 257 while (n--) { 258 __raw_writeb(*(u8 *)s, addr); 259 s++; 260 } 261} 262 263static void iomem_write16r(void __iomem *addr, const void *s, unsigned long n) 264{ 265 while (n--) { 266 __raw_writew(*(u16 *)s, addr); 267 s += 2; 268 } 269} 270 271static void iomem_write32r(void __iomem *addr, const void *s, unsigned long n) 272{ 273 while (n--) { 274 __raw_writel(*(u32 *)s, addr); 275 s += 4; 276 } 277} 278 279static const struct iomap_ops iomem_ops = { 280 .read8 = iomem_read8, 281 .read16 = iomem_read16, 282 .read16be = iomem_read16be, 283 .read32 = iomem_read32, 284 .read32be = iomem_read32be, 285#ifdef CONFIG_64BIT 286 .read64 = iomem_read64, 287 .read64be = iomem_read64be, 288#endif 289 .write8 = iomem_write8, 290 .write16 = iomem_write16, 291 .write16be = iomem_write16be, 292 .write32 = iomem_write32, 293 .write32be = iomem_write32be, 294#ifdef CONFIG_64BIT 295 .write64 = iomem_write64, 296 .write64be = iomem_write64be, 297#endif 298 .read8r = iomem_read8r, 299 .read16r = iomem_read16r, 300 .read32r = iomem_read32r, 301 .write8r = iomem_write8r, 302 .write16r = iomem_write16r, 303 .write32r = iomem_write32r, 304}; 305 306static const struct iomap_ops *iomap_ops[8] = { 307 [0] = &ioport_ops, 308 [7] = &iomem_ops 309}; 310 311 312unsigned int ioread8(const void __iomem *addr) 313{ 314 if (unlikely(INDIRECT_ADDR(addr))) 315 return iomap_ops[ADDR_TO_REGION(addr)]->read8(addr); 316 return *((u8 *)addr); 317} 318 319unsigned int ioread16(const void __iomem *addr) 320{ 321 if (unlikely(INDIRECT_ADDR(addr))) 322 return iomap_ops[ADDR_TO_REGION(addr)]->read16(addr); 323 return le16_to_cpup((u16 *)addr); 324} 325 326unsigned int ioread16be(const void __iomem *addr) 327{ 328 if (unlikely(INDIRECT_ADDR(addr))) 329 return iomap_ops[ADDR_TO_REGION(addr)]->read16be(addr); 330 return *((u16 *)addr); 331} 332 333unsigned int ioread32(const void __iomem *addr) 334{ 335 if (unlikely(INDIRECT_ADDR(addr))) 336 return iomap_ops[ADDR_TO_REGION(addr)]->read32(addr); 337 return le32_to_cpup((u32 *)addr); 338} 339 340unsigned int ioread32be(const void __iomem *addr) 341{ 342 if (unlikely(INDIRECT_ADDR(addr))) 343 return iomap_ops[ADDR_TO_REGION(addr)]->read32be(addr); 344 return *((u32 *)addr); 345} 346 347#ifdef CONFIG_64BIT 348u64 ioread64(const void __iomem *addr) 349{ 350 if (unlikely(INDIRECT_ADDR(addr))) 351 return iomap_ops[ADDR_TO_REGION(addr)]->read64(addr); 352 return le64_to_cpup((u64 *)addr); 353} 354 355u64 ioread64be(const void __iomem *addr) 356{ 357 if (unlikely(INDIRECT_ADDR(addr))) 358 return iomap_ops[ADDR_TO_REGION(addr)]->read64be(addr); 359 return *((u64 *)addr); 360} 361#endif 362 363void iowrite8(u8 datum, void __iomem *addr) 364{ 365 if (unlikely(INDIRECT_ADDR(addr))) { 366 iomap_ops[ADDR_TO_REGION(addr)]->write8(datum, addr); 367 } else { 368 *((u8 *)addr) = datum; 369 } 370} 371 372void iowrite16(u16 datum, void __iomem *addr) 373{ 374 if (unlikely(INDIRECT_ADDR(addr))) { 375 iomap_ops[ADDR_TO_REGION(addr)]->write16(datum, addr); 376 } else { 377 *((u16 *)addr) = cpu_to_le16(datum); 378 } 379} 380 381void iowrite16be(u16 datum, void __iomem *addr) 382{ 383 if (unlikely(INDIRECT_ADDR(addr))) { 384 iomap_ops[ADDR_TO_REGION(addr)]->write16be(datum, addr); 385 } else { 386 *((u16 *)addr) = datum; 387 } 388} 389 390void iowrite32(u32 datum, void __iomem *addr) 391{ 392 if (unlikely(INDIRECT_ADDR(addr))) { 393 iomap_ops[ADDR_TO_REGION(addr)]->write32(datum, addr); 394 } else { 395 *((u32 *)addr) = cpu_to_le32(datum); 396 } 397} 398 399void iowrite32be(u32 datum, void __iomem *addr) 400{ 401 if (unlikely(INDIRECT_ADDR(addr))) { 402 iomap_ops[ADDR_TO_REGION(addr)]->write32be(datum, addr); 403 } else { 404 *((u32 *)addr) = datum; 405 } 406} 407 408#ifdef CONFIG_64BIT 409void iowrite64(u64 datum, void __iomem *addr) 410{ 411 if (unlikely(INDIRECT_ADDR(addr))) { 412 iomap_ops[ADDR_TO_REGION(addr)]->write64(datum, addr); 413 } else { 414 *((u64 *)addr) = cpu_to_le64(datum); 415 } 416} 417 418void iowrite64be(u64 datum, void __iomem *addr) 419{ 420 if (unlikely(INDIRECT_ADDR(addr))) { 421 iomap_ops[ADDR_TO_REGION(addr)]->write64be(datum, addr); 422 } else { 423 *((u64 *)addr) = datum; 424 } 425} 426#endif 427 428/* Repeating interfaces */ 429 430void ioread8_rep(const void __iomem *addr, void *dst, unsigned long count) 431{ 432 if (unlikely(INDIRECT_ADDR(addr))) { 433 iomap_ops[ADDR_TO_REGION(addr)]->read8r(addr, dst, count); 434 } else { 435 while (count--) { 436 *(u8 *)dst = *(u8 *)addr; 437 dst++; 438 } 439 } 440} 441 442void ioread16_rep(const void __iomem *addr, void *dst, unsigned long count) 443{ 444 if (unlikely(INDIRECT_ADDR(addr))) { 445 iomap_ops[ADDR_TO_REGION(addr)]->read16r(addr, dst, count); 446 } else { 447 while (count--) { 448 *(u16 *)dst = *(u16 *)addr; 449 dst += 2; 450 } 451 } 452} 453 454void ioread32_rep(const void __iomem *addr, void *dst, unsigned long count) 455{ 456 if (unlikely(INDIRECT_ADDR(addr))) { 457 iomap_ops[ADDR_TO_REGION(addr)]->read32r(addr, dst, count); 458 } else { 459 while (count--) { 460 *(u32 *)dst = *(u32 *)addr; 461 dst += 4; 462 } 463 } 464} 465 466void iowrite8_rep(void __iomem *addr, const void *src, unsigned long count) 467{ 468 if (unlikely(INDIRECT_ADDR(addr))) { 469 iomap_ops[ADDR_TO_REGION(addr)]->write8r(addr, src, count); 470 } else { 471 while (count--) { 472 *(u8 *)addr = *(u8 *)src; 473 src++; 474 } 475 } 476} 477 478void iowrite16_rep(void __iomem *addr, const void *src, unsigned long count) 479{ 480 if (unlikely(INDIRECT_ADDR(addr))) { 481 iomap_ops[ADDR_TO_REGION(addr)]->write16r(addr, src, count); 482 } else { 483 while (count--) { 484 *(u16 *)addr = *(u16 *)src; 485 src += 2; 486 } 487 } 488} 489 490void iowrite32_rep(void __iomem *addr, const void *src, unsigned long count) 491{ 492 if (unlikely(INDIRECT_ADDR(addr))) { 493 iomap_ops[ADDR_TO_REGION(addr)]->write32r(addr, src, count); 494 } else { 495 while (count--) { 496 *(u32 *)addr = *(u32 *)src; 497 src += 4; 498 } 499 } 500} 501 502/* Mapping interfaces */ 503 504void __iomem *ioport_map(unsigned long port, unsigned int nr) 505{ 506 return (void __iomem *)(IOPORT_MAP_BASE | port); 507} 508 509void ioport_unmap(void __iomem *addr) 510{ 511 if (!INDIRECT_ADDR(addr)) { 512 iounmap(addr); 513 } 514} 515 516#ifdef CONFIG_PCI 517void pci_iounmap(struct pci_dev *dev, void __iomem * addr) 518{ 519 if (!INDIRECT_ADDR(addr)) { 520 iounmap(addr); 521 } 522} 523EXPORT_SYMBOL(pci_iounmap); 524#endif 525 526EXPORT_SYMBOL(ioread8); 527EXPORT_SYMBOL(ioread16); 528EXPORT_SYMBOL(ioread16be); 529EXPORT_SYMBOL(ioread32); 530EXPORT_SYMBOL(ioread32be); 531#ifdef CONFIG_64BIT 532EXPORT_SYMBOL(ioread64); 533EXPORT_SYMBOL(ioread64be); 534#endif 535EXPORT_SYMBOL(iowrite8); 536EXPORT_SYMBOL(iowrite16); 537EXPORT_SYMBOL(iowrite16be); 538EXPORT_SYMBOL(iowrite32); 539EXPORT_SYMBOL(iowrite32be); 540#ifdef CONFIG_64BIT 541EXPORT_SYMBOL(iowrite64); 542EXPORT_SYMBOL(iowrite64be); 543#endif 544EXPORT_SYMBOL(ioread8_rep); 545EXPORT_SYMBOL(ioread16_rep); 546EXPORT_SYMBOL(ioread32_rep); 547EXPORT_SYMBOL(iowrite8_rep); 548EXPORT_SYMBOL(iowrite16_rep); 549EXPORT_SYMBOL(iowrite32_rep); 550EXPORT_SYMBOL(ioport_map); 551EXPORT_SYMBOL(ioport_unmap); 552