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 44struct 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 67static unsigned int ioport_read8(void __iomem *addr) 68{ 69 return inb(ADDR2PORT(addr)); 70} 71 72static unsigned int ioport_read16(void __iomem *addr) 73{ 74 return inw(ADDR2PORT(addr)); 75} 76 77static unsigned int ioport_read32(void __iomem *addr) 78{ 79 return inl(ADDR2PORT(addr)); 80} 81 82static void ioport_write8(u8 datum, void __iomem *addr) 83{ 84 outb(datum, ADDR2PORT(addr)); 85} 86 87static void ioport_write16(u16 datum, void __iomem *addr) 88{ 89 outw(datum, ADDR2PORT(addr)); 90} 91 92static void ioport_write32(u32 datum, void __iomem *addr) 93{ 94 outl(datum, ADDR2PORT(addr)); 95} 96 97static void ioport_read8r(void __iomem *addr, void *dst, unsigned long count) 98{ 99 insb(ADDR2PORT(addr), dst, count); 100} 101 102static void ioport_read16r(void __iomem *addr, void *dst, unsigned long count) 103{ 104 insw(ADDR2PORT(addr), dst, count); 105} 106 107static void ioport_read32r(void __iomem *addr, void *dst, unsigned long count) 108{ 109 insl(ADDR2PORT(addr), dst, count); 110} 111 112static void ioport_write8r(void __iomem *addr, const void *s, unsigned long n) 113{ 114 outsb(ADDR2PORT(addr), s, n); 115} 116 117static void ioport_write16r(void __iomem *addr, const void *s, unsigned long n) 118{ 119 outsw(ADDR2PORT(addr), s, n); 120} 121 122static void ioport_write32r(void __iomem *addr, const void *s, unsigned long n) 123{ 124 outsl(ADDR2PORT(addr), s, n); 125} 126 127static 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 148static unsigned int iomem_read8(void __iomem *addr) 149{ 150 return readb(addr); 151} 152 153static unsigned int iomem_read16(void __iomem *addr) 154{ 155 return readw(addr); 156} 157 158static unsigned int iomem_read16be(void __iomem *addr) 159{ 160 return __raw_readw(addr); 161} 162 163static unsigned int iomem_read32(void __iomem *addr) 164{ 165 return readl(addr); 166} 167 168static unsigned int iomem_read32be(void __iomem *addr) 169{ 170 return __raw_readl(addr); 171} 172 173static void iomem_write8(u8 datum, void __iomem *addr) 174{ 175 writeb(datum, addr); 176} 177 178static void iomem_write16(u16 datum, void __iomem *addr) 179{ 180 writew(datum, addr); 181} 182 183static void iomem_write16be(u16 datum, void __iomem *addr) 184{ 185 __raw_writew(datum, addr); 186} 187 188static void iomem_write32(u32 datum, void __iomem *addr) 189{ 190 writel(datum, addr); 191} 192 193static void iomem_write32be(u32 datum, void __iomem *addr) 194{ 195 __raw_writel(datum, addr); 196} 197 198static 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 206static 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 214static 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 222static 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 230static 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 238static 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 246static 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 265static const struct iomap_ops *iomap_ops[8] = { 266 [0] = &ioport_ops, 267 [7] = &iomem_ops 268}; 269 270 271unsigned 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 278unsigned 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 285unsigned 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 292unsigned 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 299unsigned 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 306void 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 315void 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 324void 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 333void 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 342void 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 353void 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 365void 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 377void 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 389void 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 401void 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 413void 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 427void __iomem *ioport_map(unsigned long port, unsigned int nr) 428{ 429 return (void __iomem *)(IOPORT_MAP_BASE | port); 430} 431 432void ioport_unmap(void __iomem *addr) 433{ 434 if (!INDIRECT_ADDR(addr)) { 435 iounmap(addr); 436 } 437} 438 439void pci_iounmap(struct pci_dev *dev, void __iomem * addr) 440{ 441 if (!INDIRECT_ADDR(addr)) { 442 iounmap(addr); 443 } 444} 445 446EXPORT_SYMBOL(ioread8); 447EXPORT_SYMBOL(ioread16); 448EXPORT_SYMBOL(ioread16be); 449EXPORT_SYMBOL(ioread32); 450EXPORT_SYMBOL(ioread32be); 451EXPORT_SYMBOL(iowrite8); 452EXPORT_SYMBOL(iowrite16); 453EXPORT_SYMBOL(iowrite16be); 454EXPORT_SYMBOL(iowrite32); 455EXPORT_SYMBOL(iowrite32be); 456EXPORT_SYMBOL(ioread8_rep); 457EXPORT_SYMBOL(ioread16_rep); 458EXPORT_SYMBOL(ioread32_rep); 459EXPORT_SYMBOL(iowrite8_rep); 460EXPORT_SYMBOL(iowrite16_rep); 461EXPORT_SYMBOL(iowrite32_rep); 462EXPORT_SYMBOL(ioport_map); 463EXPORT_SYMBOL(ioport_unmap); 464EXPORT_SYMBOL(pci_iounmap); 465