Commit e7672879 authored by Linus Torvalds's avatar Linus Torvalds

Add support for "string" ioread/iowrite.

Things like SATA use this for data transfer.

Also export the iomap routines on ppc64.
parent e7c306e5
......@@ -704,6 +704,10 @@ void eeh_remove_device(struct pci_dev *dev)
}
EXPORT_SYMBOL(eeh_remove_device);
/*
* Here comes the EEH implementation of the IOMAP
* interfaces.
*/
unsigned int fastcall ioread8(void __iomem *addr)
{
return readb(addr);
......@@ -716,6 +720,9 @@ unsigned int fastcall ioread32(void __iomem *addr)
{
return readl(addr);
}
EXPORT_SYMBOL(ioread8);
EXPORT_SYMBOL(ioread16);
EXPORT_SYMBOL(ioread32);
void fastcall iowrite8(u8 val, void __iomem *addr)
{
......@@ -729,6 +736,49 @@ void fastcall iowrite32(u32 val, void __iomem *addr)
{
writel(val, addr);
}
EXPORT_SYMBOL(iowrite8);
EXPORT_SYMBOL(iowrite16);
EXPORT_SYMBOL(iowrite32);
/*
* These are the "repeat read/write" functions. Note the
* non-CPU byte order. We do things in "IO byteorder"
* here.
*
* FIXME! We could make these do EEH handling if we really
* wanted. Not clear if we do.
*/
void ioread8_rep(void __iomem *addr, void *dst, unsigned long count)
{
_insb((void *) IO_TOKEN_TO_ADDR(addr), dst, count);
}
void ioread16_rep(void __iomem *addr, void *dst, unsigned long count)
{
_insw_ns((void *) IO_TOKEN_TO_ADDR(addr), dst, count);
}
void ioread32_rep(void __iomem *addr, void *dst, unsigned long count)
{
_insl_ns((void *) IO_TOKEN_TO_ADDR(addr), dst, count);
}
EXPORT_SYMBOL(ioread8_rep);
EXPORT_SYMBOL(ioread16_rep);
EXPORT_SYMBOL(ioread32_rep);
void iowrite8_rep(void __iomem *addr, const void *src, unsigned long count)
{
_outsb((void *) IO_TOKEN_TO_ADDR(addr), src, count);
}
void iowrite16_rep(void __iomem *addr, const void *src, unsigned long count)
{
_outsw_ns((void *) IO_TOKEN_TO_ADDR(addr), src, count);
}
void iowrite32_rep(void __iomem *addr, const void *src, unsigned long count)
{
_outsl_ns((void *) IO_TOKEN_TO_ADDR(addr), src, count);
}
EXPORT_SYMBOL(iowrite8_rep);
EXPORT_SYMBOL(iowrite16_rep);
EXPORT_SYMBOL(iowrite32_rep);
void __iomem *ioport_map(unsigned long port, unsigned int len)
{
......@@ -741,6 +791,8 @@ void ioport_unmap(void __iomem *addr)
{
/* Nothing to do */
}
EXPORT_SYMBOL(ioport_map);
EXPORT_SYMBOL(ioport_unmap);
void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max)
{
......@@ -771,6 +823,8 @@ void pci_iounmap(struct pci_dev *dev, void __iomem *addr)
{
/* Nothing to do */
}
EXPORT_SYMBOL(pci_iomap);
EXPORT_SYMBOL(pci_iounmap);
/*
* If EEH is implemented, find the PCI device using given phys addr
......
......@@ -32,6 +32,25 @@ extern void fastcall iowrite8(u8, void __iomem *);
extern void fastcall iowrite16(u16, void __iomem *);
extern void fastcall iowrite32(u32, void __iomem *);
/*
* "string" versions of the above. Note that they
* use native byte ordering for the accesses (on
* the assumption that IO and memory agree on a
* byte order, and CPU byteorder is irrelevant).
*
* They do _not_ update the port address. If you
* want MMIO that copies stuff laid out in MMIO
* memory across multiple ports, use "memcpy_toio()"
* and friends.
*/
extern void fastcall ioread8_rep(void __iomem *port, void *buf, unsigned long count);
extern void fastcall ioread16_rep(void __iomem *port, void *buf, unsigned long count);
extern void fastcall ioread32_rep(void __iomem *port, void *buf, unsigned long count);
extern void fastcall iowrite8_rep(void __iomem *port, const void *buf, unsigned long count);
extern void fastcall iowrite16_rep(void __iomem *port, const void *buf, unsigned long count);
extern void fastcall iowrite32_rep(void __iomem *port, const void *buf, unsigned long count);
/* Create a virtual mapping cookie for an IO port range */
extern void __iomem *ioport_map(unsigned long port, unsigned int nr);
extern void ioport_unmap(void __iomem *);
......
......@@ -76,6 +76,91 @@ EXPORT_SYMBOL(iowrite8);
EXPORT_SYMBOL(iowrite16);
EXPORT_SYMBOL(iowrite32);
/*
* These are the "repeat MMIO read/write" functions.
* Note the "__raw" accesses, since we don't want to
* convert to CPU byte order. We write in "IO byte
* order" (we also don't have IO barriers).
*/
static inline void mmio_insb(void __iomem *addr, u8 *dst, int count)
{
while (--count >= 0) {
u8 data = __raw_readb(addr);
*dst = data;
dst++;
}
}
static inline void mmio_insw(void __iomem *addr, u16 *dst, int count)
{
while (--count >= 0) {
u16 data = __raw_readw(addr);
*dst = data;
dst++;
}
}
static inline void mmio_insl(void __iomem *addr, u32 *dst, int count)
{
while (--count >= 0) {
u32 data = __raw_readl(addr);
*dst = data;
dst++;
}
}
static inline void mmio_outsb(void __iomem *addr, const u8 *src, int count)
{
while (--count >= 0) {
__raw_writeb(*src, addr);
src++;
}
}
static inline void mmio_outsw(void __iomem *addr, const u16 *src, int count)
{
while (--count >= 0) {
__raw_writew(*src, addr);
src++;
}
}
static inline void mmio_outsl(void __iomem *addr, const u32 *src, int count)
{
while (--count >= 0) {
__raw_writel(*src, addr);
src++;
}
}
void fastcall ioread8_rep(void __iomem *addr, void *dst, unsigned long count)
{
IO_COND(addr, insb(port,dst,count), mmio_insb(addr, dst, count));
}
void fastcall ioread16_rep(void __iomem *addr, void *dst, unsigned long count)
{
IO_COND(addr, insw(port,dst,count), mmio_insw(addr, dst, count));
}
void fastcall ioread32_rep(void __iomem *addr, void *dst, unsigned long count)
{
IO_COND(addr, insl(port,dst,count), mmio_insl(addr, dst, count));
}
EXPORT_SYMBOL(ioread8_rep);
EXPORT_SYMBOL(ioread16_rep);
EXPORT_SYMBOL(ioread32_rep);
void fastcall iowrite8_rep(void __iomem *addr, const void *src, unsigned long count)
{
IO_COND(addr, outsb(port, src, count), mmio_outsb(addr, src, count));
}
void fastcall iowrite16_rep(void __iomem *addr, const void *src, unsigned long count)
{
IO_COND(addr, outsw(port, src, count), mmio_outsw(addr, src, count));
}
void fastcall iowrite32_rep(void __iomem *addr, const void *src, unsigned long count)
{
IO_COND(addr, outsl(port, src,count), mmio_outsl(addr, src, count));
}
EXPORT_SYMBOL(iowrite8_rep);
EXPORT_SYMBOL(iowrite16_rep);
EXPORT_SYMBOL(iowrite32_rep);
/* Create a virtual mapping cookie for an IO port range */
void __iomem *ioport_map(unsigned long port, unsigned int nr)
{
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment