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 43struct 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 66static unsigned int ioport_read8(void __iomem *addr) 67{ 68 return inb(ADDR2PORT(addr)); 69} 70 71static unsigned int ioport_read16(void __iomem *addr) 72{ 73 return inw(ADDR2PORT(addr)); 74} 75 76static unsigned int ioport_read32(void __iomem *addr) 77{ 78 return inl(ADDR2PORT(addr)); 79} 80 81static void ioport_write8(u8 datum, void __iomem *addr) 82{ 83 outb(datum, ADDR2PORT(addr)); 84} 85 86static void ioport_write16(u16 datum, void __iomem *addr) 87{ 88 outw(datum, ADDR2PORT(addr)); 89} 90 91static void ioport_write32(u32 datum, void __iomem *addr) 92{ 93 outl(datum, ADDR2PORT(addr)); 94} 95 96static void ioport_read8r(void __iomem *addr, void *dst, unsigned long count) 97{ 98 insb(ADDR2PORT(addr), dst, count); 99} 100 101static void ioport_read16r(void __iomem *addr, void *dst, unsigned long count) 102{ 103 insw(ADDR2PORT(addr), dst, count); 104} 105 106static void ioport_read32r(void __iomem *addr, void *dst, unsigned long count) 107{ 108 insl(ADDR2PORT(addr), dst, count); 109} 110 111static void ioport_write8r(void __iomem *addr, const void *s, unsigned long n) 112{ 113 outsb(ADDR2PORT(addr), s, n); 114} 115 116static void ioport_write16r(void __iomem *addr, const void *s, unsigned long n) 117{ 118 outsw(ADDR2PORT(addr), s, n); 119} 120 121static void ioport_write32r(void __iomem *addr, const void *s, unsigned long n) 122{ 123 outsl(ADDR2PORT(addr), s, n); 124} 125 126static 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 147static unsigned int iomem_read8(void __iomem *addr) 148{ 149 return readb(addr); 150} 151 152static unsigned int iomem_read16(void __iomem *addr) 153{ 154 return readw(addr); 155} 156 157static unsigned int iomem_read16be(void __iomem *addr) 158{ 159 return __raw_readw(addr); 160} 161 162static unsigned int iomem_read32(void __iomem *addr) 163{ 164 return readl(addr); 165} 166 167static unsigned int iomem_read32be(void __iomem *addr) 168{ 169 return __raw_readl(addr); 170} 171 172static void iomem_write8(u8 datum, void __iomem *addr) 173{ 174 writeb(datum, addr); 175} 176 177static void iomem_write16(u16 datum, void __iomem *addr) 178{ 179 writew(datum, addr); 180} 181 182static void iomem_write16be(u16 datum, void __iomem *addr) 183{ 184 __raw_writew(datum, addr); 185} 186 187static void iomem_write32(u32 datum, void __iomem *addr) 188{ 189 writel(datum, addr); 190} 191 192static void iomem_write32be(u32 datum, void __iomem *addr) 193{ 194 __raw_writel(datum, addr); 195} 196 197static 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 205static 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 213static 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 221static 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 229static 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 237static 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 245static 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 264const struct iomap_ops *iomap_ops[8] = { 265 [0] = &ioport_ops, 266 [7] = &iomem_ops 267}; 268 269 270unsigned int ioread8(void __iomem *addr) 271{ 272 if (unlikely(INDIRECT_ADDR(addr))) 273 return iomap_ops[ADDR_TO_REGION(addr)]->read8(addr); 274 return *((u8 *)addr); 275} 276 277unsigned int ioread16(void __iomem *addr) 278{ 279 if (unlikely(INDIRECT_ADDR(addr))) 280 return iomap_ops[ADDR_TO_REGION(addr)]->read16(addr); 281 return le16_to_cpup((u16 *)addr); 282} 283 284unsigned int ioread16be(void __iomem *addr) 285{ 286 if (unlikely(INDIRECT_ADDR(addr))) 287 return iomap_ops[ADDR_TO_REGION(addr)]->read16be(addr); 288 return *((u16 *)addr); 289} 290 291unsigned int ioread32(void __iomem *addr) 292{ 293 if (unlikely(INDIRECT_ADDR(addr))) 294 return iomap_ops[ADDR_TO_REGION(addr)]->read32(addr); 295 return le32_to_cpup((u32 *)addr); 296} 297 298unsigned int ioread32be(void __iomem *addr) 299{ 300 if (unlikely(INDIRECT_ADDR(addr))) 301 return iomap_ops[ADDR_TO_REGION(addr)]->read32be(addr); 302 return *((u32 *)addr); 303} 304 305void iowrite8(u8 datum, void __iomem *addr) 306{ 307 if (unlikely(INDIRECT_ADDR(addr))) { 308 iomap_ops[ADDR_TO_REGION(addr)]->write8(datum, addr); 309 } else { 310 *((u8 *)addr) = datum; 311 } 312} 313 314void iowrite16(u16 datum, void __iomem *addr) 315{ 316 if (unlikely(INDIRECT_ADDR(addr))) { 317 iomap_ops[ADDR_TO_REGION(addr)]->write16(datum, addr); 318 } else { 319 *((u16 *)addr) = cpu_to_le16(datum); 320 } 321} 322 323void iowrite16be(u16 datum, void __iomem *addr) 324{ 325 if (unlikely(INDIRECT_ADDR(addr))) { 326 iomap_ops[ADDR_TO_REGION(addr)]->write16be(datum, addr); 327 } else { 328 *((u16 *)addr) = datum; 329 } 330} 331 332void iowrite32(u32 datum, void __iomem *addr) 333{ 334 if (unlikely(INDIRECT_ADDR(addr))) { 335 iomap_ops[ADDR_TO_REGION(addr)]->write32(datum, addr); 336 } else { 337 *((u32 *)addr) = cpu_to_le32(datum); 338 } 339} 340 341void iowrite32be(u32 datum, void __iomem *addr) 342{ 343 if (unlikely(INDIRECT_ADDR(addr))) { 344 iomap_ops[ADDR_TO_REGION(addr)]->write32be(datum, addr); 345 } else { 346 *((u32 *)addr) = datum; 347 } 348} 349 350/* Repeating interfaces */ 351 352void ioread8_rep(void __iomem *addr, void *dst, unsigned long count) 353{ 354 if (unlikely(INDIRECT_ADDR(addr))) { 355 iomap_ops[ADDR_TO_REGION(addr)]->read8r(addr, dst, count); 356 } else { 357 while (count--) { 358 *(u8 *)dst = *(u8 *)addr; 359 dst++; 360 } 361 } 362} 363 364void ioread16_rep(void __iomem *addr, void *dst, unsigned long count) 365{ 366 if (unlikely(INDIRECT_ADDR(addr))) { 367 iomap_ops[ADDR_TO_REGION(addr)]->read16r(addr, dst, count); 368 } else { 369 while (count--) { 370 *(u16 *)dst = *(u16 *)addr; 371 dst += 2; 372 } 373 } 374} 375 376void ioread32_rep(void __iomem *addr, void *dst, unsigned long count) 377{ 378 if (unlikely(INDIRECT_ADDR(addr))) { 379 iomap_ops[ADDR_TO_REGION(addr)]->read32r(addr, dst, count); 380 } else { 381 while (count--) { 382 *(u32 *)dst = *(u32 *)addr; 383 dst += 4; 384 } 385 } 386} 387 388void iowrite8_rep(void __iomem *addr, const void *src, unsigned long count) 389{ 390 if (unlikely(INDIRECT_ADDR(addr))) { 391 iomap_ops[ADDR_TO_REGION(addr)]->write8r(addr, src, count); 392 } else { 393 while (count--) { 394 *(u8 *)addr = *(u8 *)src; 395 src++; 396 } 397 } 398} 399 400void iowrite16_rep(void __iomem *addr, const void *src, unsigned long count) 401{ 402 if (unlikely(INDIRECT_ADDR(addr))) { 403 iomap_ops[ADDR_TO_REGION(addr)]->write16r(addr, src, count); 404 } else { 405 while (count--) { 406 *(u16 *)addr = *(u16 *)src; 407 src += 2; 408 } 409 } 410} 411 412void iowrite32_rep(void __iomem *addr, const void *src, unsigned long count) 413{ 414 if (unlikely(INDIRECT_ADDR(addr))) { 415 iomap_ops[ADDR_TO_REGION(addr)]->write32r(addr, src, count); 416 } else { 417 while (count--) { 418 *(u32 *)addr = *(u32 *)src; 419 src += 4; 420 } 421 } 422} 423 424/* Mapping interfaces */ 425 426void __iomem *ioport_map(unsigned long port, unsigned int nr) 427{ 428 return (void __iomem *)(IOPORT_MAP_BASE | port); 429} 430 431void ioport_unmap(void __iomem *addr) 432{ 433 if (!INDIRECT_ADDR(addr)) { 434 iounmap(addr); 435 } 436} 437 438/* Create a virtual mapping cookie for a PCI BAR (memory or IO) */ 439void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen) 440{ 441 unsigned long start = pci_resource_start(dev, bar); 442 unsigned long len = pci_resource_len(dev, bar); 443 unsigned long flags = pci_resource_flags(dev, bar); 444 445 if (!len || !start) 446 return NULL; 447 if (maxlen && len > maxlen) 448 len = maxlen; 449 if (flags & IORESOURCE_IO) 450 return ioport_map(start, len); 451 if (flags & IORESOURCE_MEM) { 452 if (flags & IORESOURCE_CACHEABLE) 453 return ioremap(start, len); 454 return ioremap_nocache(start, len); 455 } 456 /* What? */ 457 return NULL; 458} 459 460void pci_iounmap(struct pci_dev *dev, void __iomem * addr) 461{ 462 if (!INDIRECT_ADDR(addr)) { 463 iounmap(addr); 464 } 465} 466 467EXPORT_SYMBOL(ioread8); 468EXPORT_SYMBOL(ioread16); 469EXPORT_SYMBOL(ioread16be); 470EXPORT_SYMBOL(ioread32); 471EXPORT_SYMBOL(ioread32be); 472EXPORT_SYMBOL(iowrite8); 473EXPORT_SYMBOL(iowrite16); 474EXPORT_SYMBOL(iowrite16be); 475EXPORT_SYMBOL(iowrite32); 476EXPORT_SYMBOL(iowrite32be); 477EXPORT_SYMBOL(ioread8_rep); 478EXPORT_SYMBOL(ioread16_rep); 479EXPORT_SYMBOL(ioread32_rep); 480EXPORT_SYMBOL(iowrite8_rep); 481EXPORT_SYMBOL(iowrite16_rep); 482EXPORT_SYMBOL(iowrite32_rep); 483EXPORT_SYMBOL(ioport_map); 484EXPORT_SYMBOL(ioport_unmap); 485EXPORT_SYMBOL(pci_iomap); 486EXPORT_SYMBOL(pci_iounmap); 487