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 45 struct iomap_ops { 46 unsigned int (*read8)(void __iomem *); 47 unsigned int (*read16)(void __iomem *); 48 unsigned int (*read16be)(void __iomem *); 49 unsigned int (*read32)(void __iomem *); 50 unsigned int (*read32be)(void __iomem *); 51 void (*write8)(u8, void __iomem *); 52 void (*write16)(u16, void __iomem *); 53 void (*write16be)(u16, void __iomem *); 54 void (*write32)(u32, void __iomem *); 55 void (*write32be)(u32, void __iomem *); 56 void (*read8r)(void __iomem *, void *, unsigned long); 57 void (*read16r)(void __iomem *, void *, unsigned long); 58 void (*read32r)(void __iomem *, void *, unsigned long); 59 void (*write8r)(void __iomem *, const void *, unsigned long); 60 void (*write16r)(void __iomem *, const void *, unsigned long); 61 void (*write32r)(void __iomem *, const void *, unsigned long); 62 }; 63 64 /* Generic ioport ops. To be replaced later by specific dino/elroy/wax code */ 65 66 #define ADDR2PORT(addr) ((unsigned long __force)(addr) & 0xffffff) 67 68 static unsigned int ioport_read8(void __iomem *addr) 69 { 70 return inb(ADDR2PORT(addr)); 71 } 72 73 static unsigned int ioport_read16(void __iomem *addr) 74 { 75 return inw(ADDR2PORT(addr)); 76 } 77 78 static unsigned int ioport_read32(void __iomem *addr) 79 { 80 return inl(ADDR2PORT(addr)); 81 } 82 83 static void ioport_write8(u8 datum, void __iomem *addr) 84 { 85 outb(datum, ADDR2PORT(addr)); 86 } 87 88 static void ioport_write16(u16 datum, void __iomem *addr) 89 { 90 outw(datum, ADDR2PORT(addr)); 91 } 92 93 static void ioport_write32(u32 datum, void __iomem *addr) 94 { 95 outl(datum, ADDR2PORT(addr)); 96 } 97 98 static void ioport_read8r(void __iomem *addr, void *dst, unsigned long count) 99 { 100 insb(ADDR2PORT(addr), dst, count); 101 } 102 103 static void ioport_read16r(void __iomem *addr, void *dst, unsigned long count) 104 { 105 insw(ADDR2PORT(addr), dst, count); 106 } 107 108 static void ioport_read32r(void __iomem *addr, void *dst, unsigned long count) 109 { 110 insl(ADDR2PORT(addr), dst, count); 111 } 112 113 static void ioport_write8r(void __iomem *addr, const void *s, unsigned long n) 114 { 115 outsb(ADDR2PORT(addr), s, n); 116 } 117 118 static void ioport_write16r(void __iomem *addr, const void *s, unsigned long n) 119 { 120 outsw(ADDR2PORT(addr), s, n); 121 } 122 123 static void ioport_write32r(void __iomem *addr, const void *s, unsigned long n) 124 { 125 outsl(ADDR2PORT(addr), s, n); 126 } 127 128 static const struct iomap_ops ioport_ops = { 129 .read8 = ioport_read8, 130 .read16 = ioport_read16, 131 .read16be = ioport_read16, 132 .read32 = ioport_read32, 133 .read32be = ioport_read32, 134 .write8 = ioport_write8, 135 .write16 = ioport_write16, 136 .write16be = ioport_write16, 137 .write32 = ioport_write32, 138 .write32be = ioport_write32, 139 .read8r = ioport_read8r, 140 .read16r = ioport_read16r, 141 .read32r = ioport_read32r, 142 .write8r = ioport_write8r, 143 .write16r = ioport_write16r, 144 .write32r = ioport_write32r, 145 }; 146 147 /* Legacy I/O memory ops */ 148 149 static unsigned int iomem_read8(void __iomem *addr) 150 { 151 return readb(addr); 152 } 153 154 static unsigned int iomem_read16(void __iomem *addr) 155 { 156 return readw(addr); 157 } 158 159 static unsigned int iomem_read16be(void __iomem *addr) 160 { 161 return __raw_readw(addr); 162 } 163 164 static unsigned int iomem_read32(void __iomem *addr) 165 { 166 return readl(addr); 167 } 168 169 static unsigned int iomem_read32be(void __iomem *addr) 170 { 171 return __raw_readl(addr); 172 } 173 174 static void iomem_write8(u8 datum, void __iomem *addr) 175 { 176 writeb(datum, addr); 177 } 178 179 static void iomem_write16(u16 datum, void __iomem *addr) 180 { 181 writew(datum, addr); 182 } 183 184 static void iomem_write16be(u16 datum, void __iomem *addr) 185 { 186 __raw_writew(datum, addr); 187 } 188 189 static void iomem_write32(u32 datum, void __iomem *addr) 190 { 191 writel(datum, addr); 192 } 193 194 static void iomem_write32be(u32 datum, void __iomem *addr) 195 { 196 __raw_writel(datum, addr); 197 } 198 199 static void iomem_read8r(void __iomem *addr, void *dst, unsigned long count) 200 { 201 while (count--) { 202 *(u8 *)dst = __raw_readb(addr); 203 dst++; 204 } 205 } 206 207 static void iomem_read16r(void __iomem *addr, void *dst, unsigned long count) 208 { 209 while (count--) { 210 *(u16 *)dst = __raw_readw(addr); 211 dst += 2; 212 } 213 } 214 215 static void iomem_read32r(void __iomem *addr, void *dst, unsigned long count) 216 { 217 while (count--) { 218 *(u32 *)dst = __raw_readl(addr); 219 dst += 4; 220 } 221 } 222 223 static void iomem_write8r(void __iomem *addr, const void *s, unsigned long n) 224 { 225 while (n--) { 226 __raw_writeb(*(u8 *)s, addr); 227 s++; 228 } 229 } 230 231 static void iomem_write16r(void __iomem *addr, const void *s, unsigned long n) 232 { 233 while (n--) { 234 __raw_writew(*(u16 *)s, addr); 235 s += 2; 236 } 237 } 238 239 static void iomem_write32r(void __iomem *addr, const void *s, unsigned long n) 240 { 241 while (n--) { 242 __raw_writel(*(u32 *)s, addr); 243 s += 4; 244 } 245 } 246 247 static const struct iomap_ops iomem_ops = { 248 .read8 = iomem_read8, 249 .read16 = iomem_read16, 250 .read16be = iomem_read16be, 251 .read32 = iomem_read32, 252 .read32be = iomem_read32be, 253 .write8 = iomem_write8, 254 .write16 = iomem_write16, 255 .write16be = iomem_write16be, 256 .write32 = iomem_write32, 257 .write32be = iomem_write32be, 258 .read8r = iomem_read8r, 259 .read16r = iomem_read16r, 260 .read32r = iomem_read32r, 261 .write8r = iomem_write8r, 262 .write16r = iomem_write16r, 263 .write32r = iomem_write32r, 264 }; 265 266 static const struct iomap_ops *iomap_ops[8] = { 267 [0] = &ioport_ops, 268 [7] = &iomem_ops 269 }; 270 271 272 unsigned int ioread8(void __iomem *addr) 273 { 274 if (unlikely(INDIRECT_ADDR(addr))) 275 return iomap_ops[ADDR_TO_REGION(addr)]->read8(addr); 276 return *((u8 *)addr); 277 } 278 279 unsigned int ioread16(void __iomem *addr) 280 { 281 if (unlikely(INDIRECT_ADDR(addr))) 282 return iomap_ops[ADDR_TO_REGION(addr)]->read16(addr); 283 return le16_to_cpup((u16 *)addr); 284 } 285 286 unsigned int ioread16be(void __iomem *addr) 287 { 288 if (unlikely(INDIRECT_ADDR(addr))) 289 return iomap_ops[ADDR_TO_REGION(addr)]->read16be(addr); 290 return *((u16 *)addr); 291 } 292 293 unsigned int ioread32(void __iomem *addr) 294 { 295 if (unlikely(INDIRECT_ADDR(addr))) 296 return iomap_ops[ADDR_TO_REGION(addr)]->read32(addr); 297 return le32_to_cpup((u32 *)addr); 298 } 299 300 unsigned int ioread32be(void __iomem *addr) 301 { 302 if (unlikely(INDIRECT_ADDR(addr))) 303 return iomap_ops[ADDR_TO_REGION(addr)]->read32be(addr); 304 return *((u32 *)addr); 305 } 306 307 void iowrite8(u8 datum, void __iomem *addr) 308 { 309 if (unlikely(INDIRECT_ADDR(addr))) { 310 iomap_ops[ADDR_TO_REGION(addr)]->write8(datum, addr); 311 } else { 312 *((u8 *)addr) = datum; 313 } 314 } 315 316 void iowrite16(u16 datum, void __iomem *addr) 317 { 318 if (unlikely(INDIRECT_ADDR(addr))) { 319 iomap_ops[ADDR_TO_REGION(addr)]->write16(datum, addr); 320 } else { 321 *((u16 *)addr) = cpu_to_le16(datum); 322 } 323 } 324 325 void iowrite16be(u16 datum, void __iomem *addr) 326 { 327 if (unlikely(INDIRECT_ADDR(addr))) { 328 iomap_ops[ADDR_TO_REGION(addr)]->write16be(datum, addr); 329 } else { 330 *((u16 *)addr) = datum; 331 } 332 } 333 334 void iowrite32(u32 datum, void __iomem *addr) 335 { 336 if (unlikely(INDIRECT_ADDR(addr))) { 337 iomap_ops[ADDR_TO_REGION(addr)]->write32(datum, addr); 338 } else { 339 *((u32 *)addr) = cpu_to_le32(datum); 340 } 341 } 342 343 void iowrite32be(u32 datum, void __iomem *addr) 344 { 345 if (unlikely(INDIRECT_ADDR(addr))) { 346 iomap_ops[ADDR_TO_REGION(addr)]->write32be(datum, addr); 347 } else { 348 *((u32 *)addr) = datum; 349 } 350 } 351 352 /* Repeating interfaces */ 353 354 void ioread8_rep(void __iomem *addr, void *dst, unsigned long count) 355 { 356 if (unlikely(INDIRECT_ADDR(addr))) { 357 iomap_ops[ADDR_TO_REGION(addr)]->read8r(addr, dst, count); 358 } else { 359 while (count--) { 360 *(u8 *)dst = *(u8 *)addr; 361 dst++; 362 } 363 } 364 } 365 366 void ioread16_rep(void __iomem *addr, void *dst, unsigned long count) 367 { 368 if (unlikely(INDIRECT_ADDR(addr))) { 369 iomap_ops[ADDR_TO_REGION(addr)]->read16r(addr, dst, count); 370 } else { 371 while (count--) { 372 *(u16 *)dst = *(u16 *)addr; 373 dst += 2; 374 } 375 } 376 } 377 378 void ioread32_rep(void __iomem *addr, void *dst, unsigned long count) 379 { 380 if (unlikely(INDIRECT_ADDR(addr))) { 381 iomap_ops[ADDR_TO_REGION(addr)]->read32r(addr, dst, count); 382 } else { 383 while (count--) { 384 *(u32 *)dst = *(u32 *)addr; 385 dst += 4; 386 } 387 } 388 } 389 390 void iowrite8_rep(void __iomem *addr, const void *src, unsigned long count) 391 { 392 if (unlikely(INDIRECT_ADDR(addr))) { 393 iomap_ops[ADDR_TO_REGION(addr)]->write8r(addr, src, count); 394 } else { 395 while (count--) { 396 *(u8 *)addr = *(u8 *)src; 397 src++; 398 } 399 } 400 } 401 402 void iowrite16_rep(void __iomem *addr, const void *src, unsigned long count) 403 { 404 if (unlikely(INDIRECT_ADDR(addr))) { 405 iomap_ops[ADDR_TO_REGION(addr)]->write16r(addr, src, count); 406 } else { 407 while (count--) { 408 *(u16 *)addr = *(u16 *)src; 409 src += 2; 410 } 411 } 412 } 413 414 void iowrite32_rep(void __iomem *addr, const void *src, unsigned long count) 415 { 416 if (unlikely(INDIRECT_ADDR(addr))) { 417 iomap_ops[ADDR_TO_REGION(addr)]->write32r(addr, src, count); 418 } else { 419 while (count--) { 420 *(u32 *)addr = *(u32 *)src; 421 src += 4; 422 } 423 } 424 } 425 426 /* Mapping interfaces */ 427 428 void __iomem *ioport_map(unsigned long port, unsigned int nr) 429 { 430 return (void __iomem *)(IOPORT_MAP_BASE | port); 431 } 432 433 void ioport_unmap(void __iomem *addr) 434 { 435 if (!INDIRECT_ADDR(addr)) { 436 iounmap(addr); 437 } 438 } 439 440 void pci_iounmap(struct pci_dev *dev, void __iomem * addr) 441 { 442 if (!INDIRECT_ADDR(addr)) { 443 iounmap(addr); 444 } 445 } 446 447 EXPORT_SYMBOL(ioread8); 448 EXPORT_SYMBOL(ioread16); 449 EXPORT_SYMBOL(ioread16be); 450 EXPORT_SYMBOL(ioread32); 451 EXPORT_SYMBOL(ioread32be); 452 EXPORT_SYMBOL(iowrite8); 453 EXPORT_SYMBOL(iowrite16); 454 EXPORT_SYMBOL(iowrite16be); 455 EXPORT_SYMBOL(iowrite32); 456 EXPORT_SYMBOL(iowrite32be); 457 EXPORT_SYMBOL(ioread8_rep); 458 EXPORT_SYMBOL(ioread16_rep); 459 EXPORT_SYMBOL(ioread32_rep); 460 EXPORT_SYMBOL(iowrite8_rep); 461 EXPORT_SYMBOL(iowrite16_rep); 462 EXPORT_SYMBOL(iowrite32_rep); 463 EXPORT_SYMBOL(ioport_map); 464 EXPORT_SYMBOL(ioport_unmap); 465 EXPORT_SYMBOL(pci_iounmap); 466