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