aboutsummaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorJames Bottomley2005-04-16 15:25:54 -0700
committerLinus Torvalds2005-04-16 15:25:54 -0700
commitdae409a27788774adb810f7cdb771ba7cce7af8a (patch)
tree7fbbbe81527c5f321f374f958a82dfa30e170850 /arch
parentc41f5eb3b8feb8772561f0e34cfee4de1fa433ec (diff)
[PATCH] add Big Endian variants of ioread/iowrite
In the new io infrastructure, all of our operators are expecting the underlying device to be little endian (because the PCI bus, their main consumer, is LE). However, there are a fair few devices and busses in the world that are actually Big Endian. There's even evidence that some of these BE bus and chip types are attached to LE systems. Thus, there's a need for a BE equivalent of our io{read,write}{16,32} operations. The attached patch adds this as io{read,write}{16,32}be. When it's in, I'll add the first consume (the 53c700 SCSI chip driver). Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/parisc/lib/iomap.c68
1 files changed, 68 insertions, 0 deletions
diff --git a/arch/parisc/lib/iomap.c b/arch/parisc/lib/iomap.c
index 290a62e7120b..01bec8fcbd0d 100644
--- a/arch/parisc/lib/iomap.c
+++ b/arch/parisc/lib/iomap.c
@@ -43,10 +43,14 @@
struct iomap_ops {
unsigned int (*read8)(void __iomem *);
unsigned int (*read16)(void __iomem *);
+ unsigned int (*read16be)(void __iomem *);
unsigned int (*read32)(void __iomem *);
+ unsigned int (*read32be)(void __iomem *);
void (*write8)(u8, void __iomem *);
void (*write16)(u16, void __iomem *);
+ void (*write16be)(u16, void __iomem *);
void (*write32)(u32, void __iomem *);
+ void (*write32be)(u32, void __iomem *);
void (*read8r)(void __iomem *, void *, unsigned long);
void (*read16r)(void __iomem *, void *, unsigned long);
void (*read32r)(void __iomem *, void *, unsigned long);
@@ -122,9 +126,13 @@ static void ioport_write32r(void __iomem *addr, const void *s, unsigned long n)
static const struct iomap_ops ioport_ops = {
ioport_read8,
ioport_read16,
+ ioport_read16,
+ ioport_read32,
ioport_read32,
ioport_write8,
ioport_write16,
+ ioport_write16,
+ ioport_write32,
ioport_write32,
ioport_read8r,
ioport_read16r,
@@ -146,11 +154,21 @@ static unsigned int iomem_read16(void __iomem *addr)
return readw(addr);
}
+static unsigned int iomem_read16be(void __iomem *addr)
+{
+ return __raw_readw(addr);
+}
+
static unsigned int iomem_read32(void __iomem *addr)
{
return readl(addr);
}
+static unsigned int iomem_read32be(void __iomem *addr)
+{
+ return __raw_readl(addr);
+}
+
static void iomem_write8(u8 datum, void __iomem *addr)
{
writeb(datum, addr);
@@ -161,11 +179,21 @@ static void iomem_write16(u16 datum, void __iomem *addr)
writew(datum, addr);
}
+static void iomem_write16be(u16 datum, void __iomem *addr)
+{
+ __raw_writew(datum, addr);
+}
+
static void iomem_write32(u32 datum, void __iomem *addr)
{
writel(datum, addr);
}
+static void iomem_write32be(u32 datum, void __iomem *addr)
+{
+ __raw_writel(datum, addr);
+}
+
static void iomem_read8r(void __iomem *addr, void *dst, unsigned long count)
{
while (count--) {
@@ -217,10 +245,14 @@ static void iomem_write32r(void __iomem *addr, const void *s, unsigned long n)
static const struct iomap_ops iomem_ops = {
iomem_read8,
iomem_read16,
+ iomem_read16be,
iomem_read32,
+ iomem_read32be,
iomem_write8,
iomem_write16,
+ iomem_write16be,
iomem_write32,
+ iomem_write32be,
iomem_read8r,
iomem_read16r,
iomem_read32r,
@@ -253,6 +285,13 @@ unsigned int ioread16(void __iomem *addr)
return le16_to_cpup((u16 *)addr);
}
+unsigned int ioread16be(void __iomem *addr)
+{
+ if (unlikely(INDIRECT_ADDR(addr)))
+ return iomap_ops[ADDR_TO_REGION(addr)]->read16be(addr);
+ return *((u16 *)addr);
+}
+
unsigned int ioread32(void __iomem *addr)
{
if (unlikely(INDIRECT_ADDR(addr)))
@@ -260,6 +299,13 @@ unsigned int ioread32(void __iomem *addr)
return le32_to_cpup((u32 *)addr);
}
+unsigned int ioread32be(void __iomem *addr)
+{
+ if (unlikely(INDIRECT_ADDR(addr)))
+ return iomap_ops[ADDR_TO_REGION(addr)]->read32be(addr);
+ return *((u32 *)addr);
+}
+
void iowrite8(u8 datum, void __iomem *addr)
{
if (unlikely(INDIRECT_ADDR(addr))) {
@@ -278,6 +324,15 @@ void iowrite16(u16 datum, void __iomem *addr)
}
}
+void iowrite16be(u16 datum, void __iomem *addr)
+{
+ if (unlikely(INDIRECT_ADDR(addr))) {
+ iomap_ops[ADDR_TO_REGION(addr)]->write16be(datum, addr);
+ } else {
+ *((u16 *)addr) = datum;
+ }
+}
+
void iowrite32(u32 datum, void __iomem *addr)
{
if (unlikely(INDIRECT_ADDR(addr))) {
@@ -287,6 +342,15 @@ void iowrite32(u32 datum, void __iomem *addr)
}
}
+void iowrite32be(u32 datum, void __iomem *addr)
+{
+ if (unlikely(INDIRECT_ADDR(addr))) {
+ iomap_ops[ADDR_TO_REGION(addr)]->write32be(datum, addr);
+ } else {
+ *((u32 *)addr) = datum;
+ }
+}
+
/* Repeating interfaces */
void ioread8_rep(void __iomem *addr, void *dst, unsigned long count)
@@ -406,10 +470,14 @@ void pci_iounmap(struct pci_dev *dev, void __iomem * addr)
EXPORT_SYMBOL(ioread8);
EXPORT_SYMBOL(ioread16);
+EXPORT_SYMBOL(ioread16be);
EXPORT_SYMBOL(ioread32);
+EXPORT_SYMBOL(ioread32be);
EXPORT_SYMBOL(iowrite8);
EXPORT_SYMBOL(iowrite16);
+EXPORT_SYMBOL(iowrite16be);
EXPORT_SYMBOL(iowrite32);
+EXPORT_SYMBOL(iowrite32be);
EXPORT_SYMBOL(ioread8_rep);
EXPORT_SYMBOL(ioread16_rep);
EXPORT_SYMBOL(ioread32_rep);