linux/arch/parisc/lib/iomap.c
<<
>>
Prefs
   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
 264static const 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        resource_size_t start = pci_resource_start(dev, bar);
 442        resource_size_t 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