linux/lib/iomap.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Implement the default iomap interfaces
   4 *
   5 * (C) Copyright 2004 Linus Torvalds
   6 */
   7#include <linux/pci.h>
   8#include <linux/io.h>
   9
  10#include <linux/export.h>
  11
  12/*
  13 * Read/write from/to an (offsettable) iomem cookie. It might be a PIO
  14 * access or a MMIO access, these functions don't care. The info is
  15 * encoded in the hardware mapping set up by the mapping functions
  16 * (or the cookie itself, depending on implementation and hw).
  17 *
  18 * The generic routines don't assume any hardware mappings, and just
  19 * encode the PIO/MMIO as part of the cookie. They coldly assume that
  20 * the MMIO IO mappings are not in the low address range.
  21 *
  22 * Architectures for which this is not true can't use this generic
  23 * implementation and should do their own copy.
  24 */
  25
  26#ifndef HAVE_ARCH_PIO_SIZE
  27/*
  28 * We encode the physical PIO addresses (0-0xffff) into the
  29 * pointer by offsetting them with a constant (0x10000) and
  30 * assuming that all the low addresses are always PIO. That means
  31 * we can do some sanity checks on the low bits, and don't
  32 * need to just take things for granted.
  33 */
  34#define PIO_OFFSET      0x10000UL
  35#define PIO_MASK        0x0ffffUL
  36#define PIO_RESERVED    0x40000UL
  37#endif
  38
  39static void bad_io_access(unsigned long port, const char *access)
  40{
  41        static int count = 10;
  42        if (count) {
  43                count--;
  44                WARN(1, KERN_ERR "Bad IO access at port %#lx (%s)\n", port, access);
  45        }
  46}
  47
  48/*
  49 * Ugly macros are a way of life.
  50 */
  51#define IO_COND(addr, is_pio, is_mmio) do {                     \
  52        unsigned long port = (unsigned long __force)addr;       \
  53        if (port >= PIO_RESERVED) {                             \
  54                is_mmio;                                        \
  55        } else if (port > PIO_OFFSET) {                         \
  56                port &= PIO_MASK;                               \
  57                is_pio;                                         \
  58        } else                                                  \
  59                bad_io_access(port, #is_pio );                  \
  60} while (0)
  61
  62#ifndef pio_read16be
  63#define pio_read16be(port) swab16(inw(port))
  64#define pio_read32be(port) swab32(inl(port))
  65#endif
  66
  67#ifndef mmio_read16be
  68#define mmio_read16be(addr) swab16(readw(addr))
  69#define mmio_read32be(addr) swab32(readl(addr))
  70#define mmio_read64be(addr) swab64(readq(addr))
  71#endif
  72
  73unsigned int ioread8(const void __iomem *addr)
  74{
  75        IO_COND(addr, return inb(port), return readb(addr));
  76        return 0xff;
  77}
  78unsigned int ioread16(const void __iomem *addr)
  79{
  80        IO_COND(addr, return inw(port), return readw(addr));
  81        return 0xffff;
  82}
  83unsigned int ioread16be(const void __iomem *addr)
  84{
  85        IO_COND(addr, return pio_read16be(port), return mmio_read16be(addr));
  86        return 0xffff;
  87}
  88unsigned int ioread32(const void __iomem *addr)
  89{
  90        IO_COND(addr, return inl(port), return readl(addr));
  91        return 0xffffffff;
  92}
  93unsigned int ioread32be(const void __iomem *addr)
  94{
  95        IO_COND(addr, return pio_read32be(port), return mmio_read32be(addr));
  96        return 0xffffffff;
  97}
  98EXPORT_SYMBOL(ioread8);
  99EXPORT_SYMBOL(ioread16);
 100EXPORT_SYMBOL(ioread16be);
 101EXPORT_SYMBOL(ioread32);
 102EXPORT_SYMBOL(ioread32be);
 103
 104#ifdef readq
 105static u64 pio_read64_lo_hi(unsigned long port)
 106{
 107        u64 lo, hi;
 108
 109        lo = inl(port);
 110        hi = inl(port + sizeof(u32));
 111
 112        return lo | (hi << 32);
 113}
 114
 115static u64 pio_read64_hi_lo(unsigned long port)
 116{
 117        u64 lo, hi;
 118
 119        hi = inl(port + sizeof(u32));
 120        lo = inl(port);
 121
 122        return lo | (hi << 32);
 123}
 124
 125static u64 pio_read64be_lo_hi(unsigned long port)
 126{
 127        u64 lo, hi;
 128
 129        lo = pio_read32be(port + sizeof(u32));
 130        hi = pio_read32be(port);
 131
 132        return lo | (hi << 32);
 133}
 134
 135static u64 pio_read64be_hi_lo(unsigned long port)
 136{
 137        u64 lo, hi;
 138
 139        hi = pio_read32be(port);
 140        lo = pio_read32be(port + sizeof(u32));
 141
 142        return lo | (hi << 32);
 143}
 144
 145u64 ioread64_lo_hi(const void __iomem *addr)
 146{
 147        IO_COND(addr, return pio_read64_lo_hi(port), return readq(addr));
 148        return 0xffffffffffffffffULL;
 149}
 150
 151u64 ioread64_hi_lo(const void __iomem *addr)
 152{
 153        IO_COND(addr, return pio_read64_hi_lo(port), return readq(addr));
 154        return 0xffffffffffffffffULL;
 155}
 156
 157u64 ioread64be_lo_hi(const void __iomem *addr)
 158{
 159        IO_COND(addr, return pio_read64be_lo_hi(port),
 160                return mmio_read64be(addr));
 161        return 0xffffffffffffffffULL;
 162}
 163
 164u64 ioread64be_hi_lo(const void __iomem *addr)
 165{
 166        IO_COND(addr, return pio_read64be_hi_lo(port),
 167                return mmio_read64be(addr));
 168        return 0xffffffffffffffffULL;
 169}
 170
 171EXPORT_SYMBOL(ioread64_lo_hi);
 172EXPORT_SYMBOL(ioread64_hi_lo);
 173EXPORT_SYMBOL(ioread64be_lo_hi);
 174EXPORT_SYMBOL(ioread64be_hi_lo);
 175
 176#endif /* readq */
 177
 178#ifndef pio_write16be
 179#define pio_write16be(val,port) outw(swab16(val),port)
 180#define pio_write32be(val,port) outl(swab32(val),port)
 181#endif
 182
 183#ifndef mmio_write16be
 184#define mmio_write16be(val,port) writew(swab16(val),port)
 185#define mmio_write32be(val,port) writel(swab32(val),port)
 186#define mmio_write64be(val,port) writeq(swab64(val),port)
 187#endif
 188
 189void iowrite8(u8 val, void __iomem *addr)
 190{
 191        IO_COND(addr, outb(val,port), writeb(val, addr));
 192}
 193void iowrite16(u16 val, void __iomem *addr)
 194{
 195        IO_COND(addr, outw(val,port), writew(val, addr));
 196}
 197void iowrite16be(u16 val, void __iomem *addr)
 198{
 199        IO_COND(addr, pio_write16be(val,port), mmio_write16be(val, addr));
 200}
 201void iowrite32(u32 val, void __iomem *addr)
 202{
 203        IO_COND(addr, outl(val,port), writel(val, addr));
 204}
 205void iowrite32be(u32 val, void __iomem *addr)
 206{
 207        IO_COND(addr, pio_write32be(val,port), mmio_write32be(val, addr));
 208}
 209EXPORT_SYMBOL(iowrite8);
 210EXPORT_SYMBOL(iowrite16);
 211EXPORT_SYMBOL(iowrite16be);
 212EXPORT_SYMBOL(iowrite32);
 213EXPORT_SYMBOL(iowrite32be);
 214
 215#ifdef writeq
 216static void pio_write64_lo_hi(u64 val, unsigned long port)
 217{
 218        outl(val, port);
 219        outl(val >> 32, port + sizeof(u32));
 220}
 221
 222static void pio_write64_hi_lo(u64 val, unsigned long port)
 223{
 224        outl(val >> 32, port + sizeof(u32));
 225        outl(val, port);
 226}
 227
 228static void pio_write64be_lo_hi(u64 val, unsigned long port)
 229{
 230        pio_write32be(val, port + sizeof(u32));
 231        pio_write32be(val >> 32, port);
 232}
 233
 234static void pio_write64be_hi_lo(u64 val, unsigned long port)
 235{
 236        pio_write32be(val >> 32, port);
 237        pio_write32be(val, port + sizeof(u32));
 238}
 239
 240void iowrite64_lo_hi(u64 val, void __iomem *addr)
 241{
 242        IO_COND(addr, pio_write64_lo_hi(val, port),
 243                writeq(val, addr));
 244}
 245
 246void iowrite64_hi_lo(u64 val, void __iomem *addr)
 247{
 248        IO_COND(addr, pio_write64_hi_lo(val, port),
 249                writeq(val, addr));
 250}
 251
 252void iowrite64be_lo_hi(u64 val, void __iomem *addr)
 253{
 254        IO_COND(addr, pio_write64be_lo_hi(val, port),
 255                mmio_write64be(val, addr));
 256}
 257
 258void iowrite64be_hi_lo(u64 val, void __iomem *addr)
 259{
 260        IO_COND(addr, pio_write64be_hi_lo(val, port),
 261                mmio_write64be(val, addr));
 262}
 263
 264EXPORT_SYMBOL(iowrite64_lo_hi);
 265EXPORT_SYMBOL(iowrite64_hi_lo);
 266EXPORT_SYMBOL(iowrite64be_lo_hi);
 267EXPORT_SYMBOL(iowrite64be_hi_lo);
 268
 269#endif /* readq */
 270
 271/*
 272 * These are the "repeat MMIO read/write" functions.
 273 * Note the "__raw" accesses, since we don't want to
 274 * convert to CPU byte order. We write in "IO byte
 275 * order" (we also don't have IO barriers).
 276 */
 277#ifndef mmio_insb
 278static inline void mmio_insb(const void __iomem *addr, u8 *dst, int count)
 279{
 280        while (--count >= 0) {
 281                u8 data = __raw_readb(addr);
 282                *dst = data;
 283                dst++;
 284        }
 285}
 286static inline void mmio_insw(const void __iomem *addr, u16 *dst, int count)
 287{
 288        while (--count >= 0) {
 289                u16 data = __raw_readw(addr);
 290                *dst = data;
 291                dst++;
 292        }
 293}
 294static inline void mmio_insl(const void __iomem *addr, u32 *dst, int count)
 295{
 296        while (--count >= 0) {
 297                u32 data = __raw_readl(addr);
 298                *dst = data;
 299                dst++;
 300        }
 301}
 302#endif
 303
 304#ifndef mmio_outsb
 305static inline void mmio_outsb(void __iomem *addr, const u8 *src, int count)
 306{
 307        while (--count >= 0) {
 308                __raw_writeb(*src, addr);
 309                src++;
 310        }
 311}
 312static inline void mmio_outsw(void __iomem *addr, const u16 *src, int count)
 313{
 314        while (--count >= 0) {
 315                __raw_writew(*src, addr);
 316                src++;
 317        }
 318}
 319static inline void mmio_outsl(void __iomem *addr, const u32 *src, int count)
 320{
 321        while (--count >= 0) {
 322                __raw_writel(*src, addr);
 323                src++;
 324        }
 325}
 326#endif
 327
 328void ioread8_rep(const void __iomem *addr, void *dst, unsigned long count)
 329{
 330        IO_COND(addr, insb(port,dst,count), mmio_insb(addr, dst, count));
 331}
 332void ioread16_rep(const void __iomem *addr, void *dst, unsigned long count)
 333{
 334        IO_COND(addr, insw(port,dst,count), mmio_insw(addr, dst, count));
 335}
 336void ioread32_rep(const void __iomem *addr, void *dst, unsigned long count)
 337{
 338        IO_COND(addr, insl(port,dst,count), mmio_insl(addr, dst, count));
 339}
 340EXPORT_SYMBOL(ioread8_rep);
 341EXPORT_SYMBOL(ioread16_rep);
 342EXPORT_SYMBOL(ioread32_rep);
 343
 344void iowrite8_rep(void __iomem *addr, const void *src, unsigned long count)
 345{
 346        IO_COND(addr, outsb(port, src, count), mmio_outsb(addr, src, count));
 347}
 348void iowrite16_rep(void __iomem *addr, const void *src, unsigned long count)
 349{
 350        IO_COND(addr, outsw(port, src, count), mmio_outsw(addr, src, count));
 351}
 352void iowrite32_rep(void __iomem *addr, const void *src, unsigned long count)
 353{
 354        IO_COND(addr, outsl(port, src,count), mmio_outsl(addr, src, count));
 355}
 356EXPORT_SYMBOL(iowrite8_rep);
 357EXPORT_SYMBOL(iowrite16_rep);
 358EXPORT_SYMBOL(iowrite32_rep);
 359
 360#ifdef CONFIG_HAS_IOPORT_MAP
 361/* Create a virtual mapping cookie for an IO port range */
 362void __iomem *ioport_map(unsigned long port, unsigned int nr)
 363{
 364        if (port > PIO_MASK)
 365                return NULL;
 366        return (void __iomem *) (unsigned long) (port + PIO_OFFSET);
 367}
 368
 369void ioport_unmap(void __iomem *addr)
 370{
 371        /* Nothing to do */
 372}
 373EXPORT_SYMBOL(ioport_map);
 374EXPORT_SYMBOL(ioport_unmap);
 375#endif /* CONFIG_HAS_IOPORT_MAP */
 376
 377#ifdef CONFIG_PCI
 378/* Hide the details if this is a MMIO or PIO address space and just do what
 379 * you expect in the correct way. */
 380void pci_iounmap(struct pci_dev *dev, void __iomem * addr)
 381{
 382        IO_COND(addr, /* nothing */, iounmap(addr));
 383}
 384EXPORT_SYMBOL(pci_iounmap);
 385#endif /* CONFIG_PCI */
 386