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