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