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