提交 3bf9a8e8 编写于 作者: B Bin Meng 提交者: Simon Glass

x86: Implement arch-specific io accessor routines

At present the generic io{read,write}{8,16,32} routines only support
MMIO access. With architecture like x86 that has a separate IO space,
these routines cannot be used to access I/O ports.

Implement x86-specific version to support both PIO and MMIO access,
so that drivers for multiple architectures can use these accessors
without the need to know whether it's MMIO or PIO.

These are ported from Linux kernel lib/iomap.c, with slight changes.
Signed-off-by: NBin Meng <bmeng.cn@gmail.com>
Reviewed-by: NSimon Glass <sjg@chromium.org>
上级 2895c4b7
......@@ -120,6 +120,7 @@ config X86
select CREATE_ARCH_SYMLINK
select DM
select DM_PCI
select HAVE_ARCH_IOMAP
select HAVE_PRIVATE_LIBGCC
select OF_CONTROL
select PCI
......
......@@ -241,6 +241,72 @@ static inline void sync(void)
#define __iormb() dmb()
#define __iowmb() dmb()
/*
* Read/write from/to an (offsettable) iomem cookie. It might be a PIO
* access or a MMIO access, these functions don't care. The info is
* encoded in the hardware mapping set up by the mapping functions
* (or the cookie itself, depending on implementation and hw).
*
* The generic routines don't assume any hardware mappings, and just
* encode the PIO/MMIO as part of the cookie. They coldly assume that
* the MMIO IO mappings are not in the low address range.
*
* Architectures for which this is not true can't use this generic
* implementation and should do their own copy.
*/
/*
* We assume that all the low physical PIO addresses (0-0xffff) always
* PIO. That means we can do some sanity checks on the low bits, and
* don't need to just take things for granted.
*/
#define PIO_RESERVED 0x10000UL
/*
* Ugly macros are a way of life.
*/
#define IO_COND(addr, is_pio, is_mmio) do { \
unsigned long port = (unsigned long __force)addr; \
if (port >= PIO_RESERVED) { \
is_mmio; \
} else { \
is_pio; \
} \
} while (0)
static inline u8 ioread8(const volatile void __iomem *addr)
{
IO_COND(addr, return inb(port), return readb(addr));
return 0xff;
}
static inline u16 ioread16(const volatile void __iomem *addr)
{
IO_COND(addr, return inw(port), return readw(addr));
return 0xffff;
}
static inline u32 ioread32(const volatile void __iomem *addr)
{
IO_COND(addr, return inl(port), return readl(addr));
return 0xffffffff;
}
static inline void iowrite8(u8 value, volatile void __iomem *addr)
{
IO_COND(addr, outb(value, port), writeb(value, addr));
}
static inline void iowrite16(u16 value, volatile void __iomem *addr)
{
IO_COND(addr, outw(value, port), writew(value, addr));
}
static inline void iowrite32(u32 value, volatile void __iomem *addr)
{
IO_COND(addr, outl(value, port), writel(value, addr));
}
#include <asm-generic/io.h>
#endif /* _ASM_IO_H */
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册