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