linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/3] asm-generic/io.h: Implement generic {read,write}s*()
@ 2014-07-09 15:11 Thierry Reding
  2014-07-09 15:11 ` [PATCH 2/3] ARM: Use include/asm-generic/io.h Thierry Reding
                   ` (3 more replies)
  0 siblings, 4 replies; 11+ messages in thread
From: Thierry Reding @ 2014-07-09 15:11 UTC (permalink / raw)
  To: linux-arm-kernel

From: Thierry Reding <treding@nvidia.com>

This patch implements generic versions of readsb(), readsw(), readsl(),
readsq(), writesb(), writesw(), writesl() and writesq(). Variants of
these string functions for I/O accesses (ins*() and outs*() as well as
ioread*_rep() and iowrite*_rep()) are now implemented in terms of the
new functions.

While at it, also make sure that any of the functions provided as
fallback for architectures that don't override them can't be overridden
subsequently.

This is compile- and runtime-tested on 32-bit and 64-bit ARM and compile
tested on Microblaze, s390, SPARC and Xtensa. For ARC, Blackfin, Metag,
OpenRISC, Score and Unicore32 which also use asm-generic/io.h I couldn't
find or build a cross-compiler that would run on my system. But by code
inspection they shouldn't break with this patch.

Signed-off-by: Thierry Reding <treding@nvidia.com>
---
 include/asm-generic/io.h | 278 +++++++++++++++++++++++++++++++++--------------
 1 file changed, 197 insertions(+), 81 deletions(-)

diff --git a/include/asm-generic/io.h b/include/asm-generic/io.h
index 975e1cc75edb..bf9d3cd4e89e 100644
--- a/include/asm-generic/io.h
+++ b/include/asm-generic/io.h
@@ -32,6 +32,7 @@
  * memory location directly.
  */
 #ifndef __raw_readb
+#define __raw_readb __raw_readb
 static inline u8 __raw_readb(const volatile void __iomem *addr)
 {
 	return *(const volatile u8 __force *) addr;
@@ -39,6 +40,7 @@ static inline u8 __raw_readb(const volatile void __iomem *addr)
 #endif
 
 #ifndef __raw_readw
+#define __raw_readw __raw_readw
 static inline u16 __raw_readw(const volatile void __iomem *addr)
 {
 	return *(const volatile u16 __force *) addr;
@@ -46,27 +48,35 @@ static inline u16 __raw_readw(const volatile void __iomem *addr)
 #endif
 
 #ifndef __raw_readl
+#define __raw_readl __raw_readl
 static inline u32 __raw_readl(const volatile void __iomem *addr)
 {
 	return *(const volatile u32 __force *) addr;
 }
 #endif
 
+#ifndef readb
 #define readb __raw_readb
+#endif
 
+#ifndef readw
 #define readw readw
 static inline u16 readw(const volatile void __iomem *addr)
 {
 	return __le16_to_cpu(__raw_readw(addr));
 }
+#endif
 
+#ifndef readl
 #define readl readl
 static inline u32 readl(const volatile void __iomem *addr)
 {
 	return __le32_to_cpu(__raw_readl(addr));
 }
+#endif
 
 #ifndef __raw_writeb
+#define __raw_writeb __raw_writeb
 static inline void __raw_writeb(u8 b, volatile void __iomem *addr)
 {
 	*(volatile u8 __force *) addr = b;
@@ -74,6 +84,7 @@ static inline void __raw_writeb(u8 b, volatile void __iomem *addr)
 #endif
 
 #ifndef __raw_writew
+#define __raw_writew __raw_writew
 static inline void __raw_writew(u16 b, volatile void __iomem *addr)
 {
 	*(volatile u16 __force *) addr = b;
@@ -81,78 +92,225 @@ static inline void __raw_writew(u16 b, volatile void __iomem *addr)
 #endif
 
 #ifndef __raw_writel
+#define __raw_writel __raw_writel
 static inline void __raw_writel(u32 b, volatile void __iomem *addr)
 {
 	*(volatile u32 __force *) addr = b;
 }
 #endif
 
+#ifndef writeb
 #define writeb __raw_writeb
+#endif
+
+#ifndef writew
 #define writew(b,addr) __raw_writew(__cpu_to_le16(b),addr)
+#endif
+
+#ifndef writel
 #define writel(b,addr) __raw_writel(__cpu_to_le32(b),addr)
+#endif
 
 #ifdef CONFIG_64BIT
 #ifndef __raw_readq
+#define __raw_readq __raw_readq
 static inline u64 __raw_readq(const volatile void __iomem *addr)
 {
 	return *(const volatile u64 __force *) addr;
 }
 #endif
 
+#ifndef readq
 #define readq readq
 static inline u64 readq(const volatile void __iomem *addr)
 {
 	return __le64_to_cpu(__raw_readq(addr));
 }
+#endif
 
 #ifndef __raw_writeq
+#define __raw_writeq __raw_writeq
 static inline void __raw_writeq(u64 b, volatile void __iomem *addr)
 {
 	*(volatile u64 __force *) addr = b;
 }
 #endif
 
+#ifndef writeq
 #define writeq(b, addr) __raw_writeq(__cpu_to_le64(b), addr)
+#endif
+#endif /* CONFIG_64BIT */
+
+#ifndef readsb
+#define readsb readsb
+static inline void readsb(const void __iomem *addr, void *buffer, int count)
+{
+	if (count) {
+		u8 *buf = buffer;
+		do {
+			u8 x = __raw_readb(addr);
+			*buf++ = x;
+		} while (--count);
+	}
+}
+#endif
+
+#ifndef readsw
+#define readsw readsw
+static inline void readsw(const void __iomem *addr, void *buffer, int count)
+{
+	if (count) {
+		u16 *buf = buffer;
+		do {
+			u16 x = __raw_readw(addr);
+			*buf++ = x;
+		} while (--count);
+	}
+}
+#endif
+
+#ifndef readsl
+#define readsl readsl
+static inline void readsl(const void __iomem *addr, void *buffer, int count)
+{
+	if (count) {
+		u32 *buf = buffer;
+		do {
+			u32 x = __raw_readl(addr);
+			*buf++ = x;
+		} while (--count);
+	}
+}
+#endif
+
+#ifndef writesb
+#define writesb writesb
+static inline void writesb(void __iomem *addr, const void *buffer, int count)
+{
+	if (count) {
+		const u8 *buf = buffer;
+		do {
+			__raw_writeb(*buf++, addr);
+		} while (--count);
+	}
+}
+#endif
+
+#ifndef writesw
+#define writesw writesw
+static inline void writesw(void __iomem *addr, const void *buffer, int count)
+{
+	if (count) {
+		const u16 *buf = buffer;
+		do {
+			__raw_writew(*buf++, addr);
+		} while (--count);
+	}
+}
+#endif
+
+#ifndef writesl
+#define writesl writesl
+static inline void writesl(void __iomem *addr, const void *buffer, int count)
+{
+	if (count) {
+		const u32 *buf = buffer;
+		do {
+			__raw_writel(*buf++, addr);
+		} while (--count);
+	}
+}
+#endif
+
+#ifdef CONFIG_64BIT
+#ifndef readsq
+#define readsq readsq
+static inline void readsq(const void __iomem *addr, void *buffer, int count)
+{
+	if (count) {
+		u64 *buf = buffer;
+		do {
+			u64 x = __raw_readq(addr);
+			*buf++ = x;
+		} while (--count);
+	}
+}
+#endif
+
+#ifndef writesq
+#define writesq writesq
+static inline void writesq(void __iomem *addr, const void *buffer, int count)
+{
+	if (count) {
+		const u64 *buf = buffer;
+		do {
+			__raw_writeq(*buf++, addr);
+		} while (--count);
+	}
+}
+#endif
 #endif /* CONFIG_64BIT */
 
 #ifndef PCI_IOBASE
 #define PCI_IOBASE ((void __iomem *) 0)
 #endif
 
+#ifndef IO_SPACE_LIMIT
+#define IO_SPACE_LIMIT 0xffff
+#endif
+
 /*****************************************************************************/
 /*
  * traditional input/output functions
  */
 
+#ifndef inb
+#define inb inb
 static inline u8 inb(unsigned long addr)
 {
-	return readb(addr + PCI_IOBASE);
+	return readb(PCI_IOBASE + addr);
 }
+#endif
 
+#ifndef inw
+#define inw inw
 static inline u16 inw(unsigned long addr)
 {
-	return readw(addr + PCI_IOBASE);
+	return readw(PCI_IOBASE + addr);
 }
+#endif
 
+#ifndef inl
+#define inl inl
 static inline u32 inl(unsigned long addr)
 {
-	return readl(addr + PCI_IOBASE);
+	return readl(PCI_IOBASE + addr);
 }
+#endif
 
+#ifndef outb
+#define outb outb
 static inline void outb(u8 b, unsigned long addr)
 {
-	writeb(b, addr + PCI_IOBASE);
+	writeb(b, PCI_IOBASE + addr);
 }
+#endif
 
+#ifndef outw
+#define outw outw
 static inline void outw(u16 b, unsigned long addr)
 {
-	writew(b, addr + PCI_IOBASE);
+	writew(b, PCI_IOBASE + addr);
 }
+#endif
 
+#ifndef outl
+#define outl outl
 static inline void outl(u32 b, unsigned long addr)
 {
-	writel(b, addr + PCI_IOBASE);
+	writel(b, PCI_IOBASE + addr);
 }
+#endif
 
 #define inb_p(addr)	inb(addr)
 #define inw_p(addr)	inw(addr)
@@ -162,80 +320,37 @@ static inline void outl(u32 b, unsigned long addr)
 #define outl_p(x, addr)	outl((x), (addr))
 
 #ifndef insb
-static inline void insb(unsigned long addr, void *buffer, int count)
-{
-	if (count) {
-		u8 *buf = buffer;
-		do {
-			u8 x = __raw_readb(addr + PCI_IOBASE);
-			*buf++ = x;
-		} while (--count);
-	}
-}
+#define insb(addr, buffer, count) readsb(PCI_IOBASE + addr, buffer, count)
 #endif
 
 #ifndef insw
-static inline void insw(unsigned long addr, void *buffer, int count)
-{
-	if (count) {
-		u16 *buf = buffer;
-		do {
-			u16 x = __raw_readw(addr + PCI_IOBASE);
-			*buf++ = x;
-		} while (--count);
-	}
-}
+#define insw(addr, buffer, count) readsw(PCI_IOBASE + addr, buffer, count)
 #endif
 
 #ifndef insl
-static inline void insl(unsigned long addr, void *buffer, int count)
-{
-	if (count) {
-		u32 *buf = buffer;
-		do {
-			u32 x = __raw_readl(addr + PCI_IOBASE);
-			*buf++ = x;
-		} while (--count);
-	}
-}
+#define insl(addr, buffer, count) readsl(PCI_IOBASE + addr, buffer, count)
 #endif
 
 #ifndef outsb
-static inline void outsb(unsigned long addr, const void *buffer, int count)
-{
-	if (count) {
-		const u8 *buf = buffer;
-		do {
-			__raw_writeb(*buf++, addr + PCI_IOBASE);
-		} while (--count);
-	}
-}
+#define outsb(addr, buffer, count) writesb(PCI_IOBASE + addr, buffer, count)
 #endif
 
 #ifndef outsw
-static inline void outsw(unsigned long addr, const void *buffer, int count)
-{
-	if (count) {
-		const u16 *buf = buffer;
-		do {
-			__raw_writew(*buf++, addr + PCI_IOBASE);
-		} while (--count);
-	}
-}
+#define outsw(addr, buffer, count) writesw(PCI_IOBASE + addr, buffer, count)
 #endif
 
 #ifndef outsl
-static inline void outsl(unsigned long addr, const void *buffer, int count)
-{
-	if (count) {
-		const u32 *buf = buffer;
-		do {
-			__raw_writel(*buf++, addr + PCI_IOBASE);
-		} while (--count);
-	}
-}
+#define outsl(addr, buffer, count) writesl(PCI_IOBASE + addr, buffer, count)
 #endif
 
+#define insb_p(port,to,len)	insb(port,to,len)
+#define insw_p(port,to,len)	insw(port,to,len)
+#define insl_p(port,to,len)	insl(port,to,len)
+
+#define outsb_p(port,from,len)	outsb(port,from,len)
+#define outsw_p(port,from,len)	outsw(port,from,len)
+#define outsl_p(port,from,len)	outsl(port,from,len)
+
 #ifndef CONFIG_GENERIC_IOMAP
 #define ioread8(addr)		readb(addr)
 #define ioread16(addr)		readw(addr)
@@ -249,24 +364,14 @@ static inline void outsl(unsigned long addr, const void *buffer, int count)
 #define iowrite32(v, addr)	writel((v), (addr))
 #define iowrite32be(v, addr)	__raw_writel(__cpu_to_be32(v), addr)
 
-#define ioread8_rep(p, dst, count) \
-	insb((unsigned long) (p), (dst), (count))
-#define ioread16_rep(p, dst, count) \
-	insw((unsigned long) (p), (dst), (count))
-#define ioread32_rep(p, dst, count) \
-	insl((unsigned long) (p), (dst), (count))
-
-#define iowrite8_rep(p, src, count) \
-	outsb((unsigned long) (p), (src), (count))
-#define iowrite16_rep(p, src, count) \
-	outsw((unsigned long) (p), (src), (count))
-#define iowrite32_rep(p, src, count) \
-	outsl((unsigned long) (p), (src), (count))
-#endif /* CONFIG_GENERIC_IOMAP */
+#define ioread8_rep(p, dst, count) readsb(p, dst, count)
+#define ioread16_rep(p, dst, count) readsw(p, dst, count)
+#define ioread32_rep(p, dst, count) readsl(p, dst, count)
 
-#ifndef IO_SPACE_LIMIT
-#define IO_SPACE_LIMIT 0xffff
-#endif
+#define iowrite8_rep(p, src, count) writesb(p, src, count)
+#define iowrite16_rep(p, src, count) writesw(p, src, count)
+#define iowrite32_rep(p, src, count) writesl(p, src, count)
+#endif /* CONFIG_GENERIC_IOMAP */
 
 #ifdef __KERNEL__
 
@@ -278,6 +383,7 @@ struct pci_dev;
 extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max);
 
 #ifndef pci_iounmap
+#define pci_iounmap pci_iounmap
 static inline void pci_iounmap(struct pci_dev *dev, void __iomem *p)
 {
 }
@@ -289,11 +395,15 @@ static inline void pci_iounmap(struct pci_dev *dev, void __iomem *p)
  * These are pretty trivial
  */
 #ifndef virt_to_phys
+#define virt_to_phys virt_to_phys
 static inline unsigned long virt_to_phys(volatile void *address)
 {
 	return __pa((unsigned long)address);
 }
+#endif
 
+#ifndef phys_to_virt
+#define phys_to_virt phys_to_virt
 static inline void *phys_to_virt(unsigned long address)
 {
 	return __va(address);
@@ -329,14 +439,20 @@ static inline void iounmap(void __iomem *addr)
 
 #ifdef CONFIG_HAS_IOPORT_MAP
 #ifndef CONFIG_GENERIC_IOMAP
+#ifndef ioport_map
+#define ioport_map ioport_map
 static inline void __iomem *ioport_map(unsigned long port, unsigned int nr)
 {
-	return (void __iomem *) port;
+	return PCI_IOBASE + port;
 }
+#endif
 
+#ifndef ioport_unmap
+#define ioport_unmap ioport_unmap
 static inline void ioport_unmap(void __iomem *p)
 {
 }
+#endif
 #else /* CONFIG_GENERIC_IOMAP */
 extern void __iomem *ioport_map(unsigned long port, unsigned int nr);
 extern void ioport_unmap(void __iomem *p);
-- 
2.0.1

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 2/3] ARM: Use include/asm-generic/io.h
  2014-07-09 15:11 [PATCH 1/3] asm-generic/io.h: Implement generic {read,write}s*() Thierry Reding
@ 2014-07-09 15:11 ` Thierry Reding
  2014-07-09 15:11 ` [PATCH 3/3] arm64: " Thierry Reding
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 11+ messages in thread
From: Thierry Reding @ 2014-07-09 15:11 UTC (permalink / raw)
  To: linux-arm-kernel

From: Thierry Reding <treding@nvidia.com>

Include the generic I/O header file so that duplicate implementations
can be removed. This will also help to establish consistency across more
architectures regarding which accessors they support.

Signed-off-by: Thierry Reding <treding@nvidia.com>
---
 arch/arm/include/asm/io.h     | 52 +++++++++----------------------------------
 arch/arm/include/asm/memory.h |  2 ++
 2 files changed, 13 insertions(+), 41 deletions(-)

diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h
index a78562f21aab..ef54f5c8a7ae 100644
--- a/arch/arm/include/asm/io.h
+++ b/arch/arm/include/asm/io.h
@@ -69,6 +69,7 @@ extern void __raw_readsl(const void __iomem *addr, void *data, int longlen);
  * writeback addressing modes as these incur a significant performance
  * overhead (the address generation must be emulated in software).
  */
+#define __raw_writew __raw_writew
 static inline void __raw_writew(u16 val, volatile void __iomem *addr)
 {
 	asm volatile("strh %1, %0"
@@ -76,6 +77,7 @@ static inline void __raw_writew(u16 val, volatile void __iomem *addr)
 		     : "r" (val));
 }
 
+#define __raw_readw __raw_readw
 static inline u16 __raw_readw(const volatile void __iomem *addr)
 {
 	u16 val;
@@ -86,6 +88,7 @@ static inline u16 __raw_readw(const volatile void __iomem *addr)
 }
 #endif
 
+#define __raw_writeb __raw_writeb
 static inline void __raw_writeb(u8 val, volatile void __iomem *addr)
 {
 	asm volatile("strb %1, %0"
@@ -93,6 +96,7 @@ static inline void __raw_writeb(u8 val, volatile void __iomem *addr)
 		     : "r" (val));
 }
 
+#define __raw_writel __raw_writel
 static inline void __raw_writel(u32 val, volatile void __iomem *addr)
 {
 	asm volatile("str %1, %0"
@@ -100,6 +104,7 @@ static inline void __raw_writel(u32 val, volatile void __iomem *addr)
 		     : "r" (val));
 }
 
+#define __raw_readb __raw_readb
 static inline u8 __raw_readb(const volatile void __iomem *addr)
 {
 	u8 val;
@@ -109,6 +114,7 @@ static inline u8 __raw_readb(const volatile void __iomem *addr)
 	return val;
 }
 
+#define __raw_readl __raw_readl
 static inline u32 __raw_readl(const volatile void __iomem *addr)
 {
 	u32 val;
@@ -267,20 +273,6 @@ extern void pci_iounmap_io(unsigned int offset);
 #define insl(p,d,l)		__raw_readsl(__io(p),d,l)
 #endif
 
-#define outb_p(val,port)	outb((val),(port))
-#define outw_p(val,port)	outw((val),(port))
-#define outl_p(val,port)	outl((val),(port))
-#define inb_p(port)		inb((port))
-#define inw_p(port)		inw((port))
-#define inl_p(port)		inl((port))
-
-#define outsb_p(port,from,len)	outsb(port,from,len)
-#define outsw_p(port,from,len)	outsw(port,from,len)
-#define outsl_p(port,from,len)	outsl(port,from,len)
-#define insb_p(port,to,len)	insb(port,to,len)
-#define insw_p(port,to,len)	insw(port,to,len)
-#define insl_p(port,to,len)	insl(port,to,len)
-
 /*
  * String version of IO memory access ops:
  */
@@ -346,40 +338,18 @@ extern void _memset_io(volatile void __iomem *, int, size_t);
 #define ioremap_wc(cookie,size)		__arm_ioremap((cookie), (size), MT_DEVICE_WC)
 #define iounmap				__arm_iounmap
 
-/*
- * io{read,write}{8,16,32} macros
- */
-#ifndef ioread8
-#define ioread8(p)	({ unsigned int __v = __raw_readb(p); __iormb(); __v; })
-#define ioread16(p)	({ unsigned int __v = le16_to_cpu((__force __le16)__raw_readw(p)); __iormb(); __v; })
-#define ioread32(p)	({ unsigned int __v = le32_to_cpu((__force __le32)__raw_readl(p)); __iormb(); __v; })
-
-#define ioread16be(p)	({ unsigned int __v = be16_to_cpu((__force __be16)__raw_readw(p)); __iormb(); __v; })
-#define ioread32be(p)	({ unsigned int __v = be32_to_cpu((__force __be32)__raw_readl(p)); __iormb(); __v; })
-
-#define iowrite8(v,p)	({ __iowmb(); __raw_writeb(v, p); })
-#define iowrite16(v,p)	({ __iowmb(); __raw_writew((__force __u16)cpu_to_le16(v), p); })
-#define iowrite32(v,p)	({ __iowmb(); __raw_writel((__force __u32)cpu_to_le32(v), p); })
-
-#define iowrite16be(v,p) ({ __iowmb(); __raw_writew((__force __u16)cpu_to_be16(v), p); })
-#define iowrite32be(v,p) ({ __iowmb(); __raw_writel((__force __u32)cpu_to_be32(v), p); })
-
-#define ioread8_rep(p,d,c)	__raw_readsb(p,d,c)
-#define ioread16_rep(p,d,c)	__raw_readsw(p,d,c)
-#define ioread32_rep(p,d,c)	__raw_readsl(p,d,c)
-
-#define iowrite8_rep(p,s,c)	__raw_writesb(p,s,c)
-#define iowrite16_rep(p,s,c)	__raw_writesw(p,s,c)
-#define iowrite32_rep(p,s,c)	__raw_writesl(p,s,c)
-
+#define ioport_map ioport_map
 extern void __iomem *ioport_map(unsigned long port, unsigned int nr);
+#define ioport_unmap ioport_unmap
 extern void ioport_unmap(void __iomem *addr);
-#endif
 
 struct pci_dev;
 
+#define pci_iounmap pci_iounmap
 extern void pci_iounmap(struct pci_dev *dev, void __iomem *addr);
 
+#include <asm-generic/io.h>
+
 /*
  * can the hardware map this into one segment or not, given no other
  * constraints.
diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h
index 2b751464d6ff..35ae6eaf33b2 100644
--- a/arch/arm/include/asm/memory.h
+++ b/arch/arm/include/asm/memory.h
@@ -278,11 +278,13 @@ static inline unsigned long __phys_to_virt(phys_addr_t x)
  * translation for translating DMA addresses.  Use the driver
  * DMA support - see dma-mapping.h.
  */
+#define virt_to_phys virt_to_phys
 static inline phys_addr_t virt_to_phys(const volatile void *x)
 {
 	return __virt_to_phys((unsigned long)(x));
 }
 
+#define phys_to_virt phys_to_virt
 static inline void *phys_to_virt(phys_addr_t x)
 {
 	return (void *)__phys_to_virt(x);
-- 
2.0.1

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 3/3] arm64: Use include/asm-generic/io.h
  2014-07-09 15:11 [PATCH 1/3] asm-generic/io.h: Implement generic {read,write}s*() Thierry Reding
  2014-07-09 15:11 ` [PATCH 2/3] ARM: Use include/asm-generic/io.h Thierry Reding
@ 2014-07-09 15:11 ` Thierry Reding
  2014-07-10 11:00   ` Catalin Marinas
  2014-07-09 17:38 ` [PATCH 1/3] asm-generic/io.h: Implement generic {read,write}s*() Sam Ravnborg
  2014-07-10 10:38 ` Arnd Bergmann
  3 siblings, 1 reply; 11+ messages in thread
From: Thierry Reding @ 2014-07-09 15:11 UTC (permalink / raw)
  To: linux-arm-kernel

From: Thierry Reding <treding@nvidia.com>

Include the generic I/O header file so that duplicate implementations
can be removed. This will also help to establish consistency across more
architectures regarding which accessors they support.

Signed-off-by: Thierry Reding <treding@nvidia.com>
---
 arch/arm64/Kconfig              |  1 -
 arch/arm64/include/asm/io.h     | 99 ++++-------------------------------------
 arch/arm64/include/asm/memory.h |  2 +
 3 files changed, 11 insertions(+), 91 deletions(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index a497556520d4..a428ac1573e7 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -20,7 +20,6 @@ config ARM64
 	select GENERIC_CLOCKEVENTS_BROADCAST if SMP
 	select GENERIC_CPU_AUTOPROBE
 	select GENERIC_EARLY_IOREMAP
-	select GENERIC_IOMAP
 	select GENERIC_IRQ_PROBE
 	select GENERIC_IRQ_SHOW
 	select GENERIC_SCHED_CLOCK
diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h
index e0ecdcf6632d..00c7f9faf2a3 100644
--- a/arch/arm64/include/asm/io.h
+++ b/arch/arm64/include/asm/io.h
@@ -34,26 +34,31 @@
 /*
  * Generic IO read/write.  These perform native-endian accesses.
  */
+#define __raw_writeb __raw_writeb
 static inline void __raw_writeb(u8 val, volatile void __iomem *addr)
 {
 	asm volatile("strb %w0, [%1]" : : "r" (val), "r" (addr));
 }
 
+#define __raw_writew __raw_writew
 static inline void __raw_writew(u16 val, volatile void __iomem *addr)
 {
 	asm volatile("strh %w0, [%1]" : : "r" (val), "r" (addr));
 }
 
+#define __raw_writel __raw_writel
 static inline void __raw_writel(u32 val, volatile void __iomem *addr)
 {
 	asm volatile("str %w0, [%1]" : : "r" (val), "r" (addr));
 }
 
+#define __raw_writeq __raw_writeq
 static inline void __raw_writeq(u64 val, volatile void __iomem *addr)
 {
 	asm volatile("str %0, [%1]" : : "r" (val), "r" (addr));
 }
 
+#define __raw_readb __raw_readb
 static inline u8 __raw_readb(const volatile void __iomem *addr)
 {
 	u8 val;
@@ -61,6 +66,7 @@ static inline u8 __raw_readb(const volatile void __iomem *addr)
 	return val;
 }
 
+#define __raw_readw __raw_readw
 static inline u16 __raw_readw(const volatile void __iomem *addr)
 {
 	u16 val;
@@ -68,6 +74,7 @@ static inline u16 __raw_readw(const volatile void __iomem *addr)
 	return val;
 }
 
+#define __raw_readl __raw_readl
 static inline u32 __raw_readl(const volatile void __iomem *addr)
 {
 	u32 val;
@@ -75,6 +82,7 @@ static inline u32 __raw_readl(const volatile void __iomem *addr)
 	return val;
 }
 
+#define __raw_readq __raw_readq
 static inline u64 __raw_readq(const volatile void __iomem *addr)
 {
 	u64 val;
@@ -124,94 +132,6 @@ static inline u64 __raw_readq(const volatile void __iomem *addr)
 #define IO_SPACE_LIMIT		0xffff
 #define PCI_IOBASE		((void __iomem *)(MODULES_VADDR - SZ_32M))
 
-static inline u8 inb(unsigned long addr)
-{
-	return readb(addr + PCI_IOBASE);
-}
-
-static inline u16 inw(unsigned long addr)
-{
-	return readw(addr + PCI_IOBASE);
-}
-
-static inline u32 inl(unsigned long addr)
-{
-	return readl(addr + PCI_IOBASE);
-}
-
-static inline void outb(u8 b, unsigned long addr)
-{
-	writeb(b, addr + PCI_IOBASE);
-}
-
-static inline void outw(u16 b, unsigned long addr)
-{
-	writew(b, addr + PCI_IOBASE);
-}
-
-static inline void outl(u32 b, unsigned long addr)
-{
-	writel(b, addr + PCI_IOBASE);
-}
-
-#define inb_p(addr)	inb(addr)
-#define inw_p(addr)	inw(addr)
-#define inl_p(addr)	inl(addr)
-
-#define outb_p(x, addr)	outb((x), (addr))
-#define outw_p(x, addr)	outw((x), (addr))
-#define outl_p(x, addr)	outl((x), (addr))
-
-static inline void insb(unsigned long addr, void *buffer, int count)
-{
-	u8 *buf = buffer;
-	while (count--)
-		*buf++ = __raw_readb(addr + PCI_IOBASE);
-}
-
-static inline void insw(unsigned long addr, void *buffer, int count)
-{
-	u16 *buf = buffer;
-	while (count--)
-		*buf++ = __raw_readw(addr + PCI_IOBASE);
-}
-
-static inline void insl(unsigned long addr, void *buffer, int count)
-{
-	u32 *buf = buffer;
-	while (count--)
-		*buf++ = __raw_readl(addr + PCI_IOBASE);
-}
-
-static inline void outsb(unsigned long addr, const void *buffer, int count)
-{
-	const u8 *buf = buffer;
-	while (count--)
-		__raw_writeb(*buf++, addr + PCI_IOBASE);
-}
-
-static inline void outsw(unsigned long addr, const void *buffer, int count)
-{
-	const u16 *buf = buffer;
-	while (count--)
-		__raw_writew(*buf++, addr + PCI_IOBASE);
-}
-
-static inline void outsl(unsigned long addr, const void *buffer, int count)
-{
-	const u32 *buf = buffer;
-	while (count--)
-		__raw_writel(*buf++, addr + PCI_IOBASE);
-}
-
-#define insb_p(port,to,len)	insb(port,to,len)
-#define insw_p(port,to,len)	insw(port,to,len)
-#define insl_p(port,to,len)	insl(port,to,len)
-
-#define outsb_p(port,from,len)	outsb(port,from,len)
-#define outsw_p(port,from,len)	outsw(port,from,len)
-#define outsl_p(port,from,len)	outsl(port,from,len)
-
 /*
  * String version of I/O memory access operations.
  */
@@ -235,8 +155,7 @@ extern void __iomem *ioremap_cache(phys_addr_t phys_addr, size_t size);
 #define ioremap_wc(addr, size)		__ioremap((addr), (size), __pgprot(PROT_NORMAL_NC))
 #define iounmap				__iounmap
 
-#define ARCH_HAS_IOREMAP_WC
-#include <asm-generic/iomap.h>
+#include <asm-generic/io.h>
 
 /*
  * More restrictive address range checking than the default implementation
diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
index 993bce527b85..ca6116de3155 100644
--- a/arch/arm64/include/asm/memory.h
+++ b/arch/arm64/include/asm/memory.h
@@ -122,11 +122,13 @@ extern phys_addr_t		memstart_addr;
  * translation for translating DMA addresses.  Use the driver
  * DMA support - see dma-mapping.h.
  */
+#define virt_to_phys virt_to_phys
 static inline phys_addr_t virt_to_phys(const volatile void *x)
 {
 	return __virt_to_phys((unsigned long)(x));
 }
 
+#define phys_to_virt phys_to_virt
 static inline void *phys_to_virt(phys_addr_t x)
 {
 	return (void *)(__phys_to_virt(x));
-- 
2.0.1

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 1/3] asm-generic/io.h: Implement generic {read,write}s*()
  2014-07-09 15:11 [PATCH 1/3] asm-generic/io.h: Implement generic {read,write}s*() Thierry Reding
  2014-07-09 15:11 ` [PATCH 2/3] ARM: Use include/asm-generic/io.h Thierry Reding
  2014-07-09 15:11 ` [PATCH 3/3] arm64: " Thierry Reding
@ 2014-07-09 17:38 ` Sam Ravnborg
  2014-07-10 10:38 ` Arnd Bergmann
  3 siblings, 0 replies; 11+ messages in thread
From: Sam Ravnborg @ 2014-07-09 17:38 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Jul 09, 2014 at 05:11:37PM +0200, Thierry Reding wrote:
> From: Thierry Reding <treding@nvidia.com>
> 
> This patch implements generic versions of readsb(), readsw(), readsl(),
> readsq(), writesb(), writesw(), writesl() and writesq(). Variants of
> these string functions for I/O accesses (ins*() and outs*() as well as
> ioread*_rep() and iowrite*_rep()) are now implemented in terms of the
> new functions.
> 
> While at it, also make sure that any of the functions provided as
> fallback for architectures that don't override them can't be overridden
> subsequently.
> 
> This is compile- and runtime-tested on 32-bit and 64-bit ARM and compile
> tested on Microblaze, s390, SPARC and Xtensa. For ARC, Blackfin, Metag,
> OpenRISC, Score and Unicore32 which also use asm-generic/io.h I couldn't
> find or build a cross-compiler that would run on my system. But by code
> inspection they shouldn't break with this patch.

Looks good. When this is in mainline I will try to convert sparc64
to use asm-generic/io.h too.
Last I tried this did not fly because there were some #define
missing and then I lost track of it.

	Sam

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 1/3] asm-generic/io.h: Implement generic {read,write}s*()
  2014-07-09 15:11 [PATCH 1/3] asm-generic/io.h: Implement generic {read,write}s*() Thierry Reding
                   ` (2 preceding siblings ...)
  2014-07-09 17:38 ` [PATCH 1/3] asm-generic/io.h: Implement generic {read,write}s*() Sam Ravnborg
@ 2014-07-10 10:38 ` Arnd Bergmann
  3 siblings, 0 replies; 11+ messages in thread
From: Arnd Bergmann @ 2014-07-10 10:38 UTC (permalink / raw)
  To: linux-arm-kernel

On Wednesday 09 July 2014, Thierry Reding wrote:
> 
> From: Thierry Reding <treding@nvidia.com>
> 
> This patch implements generic versions of readsb(), readsw(), readsl(),
> readsq(), writesb(), writesw(), writesl() and writesq(). Variants of
> these string functions for I/O accesses (ins*() and outs*() as well as
> ioread*_rep() and iowrite*_rep()) are now implemented in terms of the
> new functions.
> 
> While at it, also make sure that any of the functions provided as
> fallback for architectures that don't override them can't be overridden
> subsequently.
> 
> This is compile- and runtime-tested on 32-bit and 64-bit ARM and compile
> tested on Microblaze, s390, SPARC and Xtensa. For ARC, Blackfin, Metag,
> OpenRISC, Score and Unicore32 which also use asm-generic/io.h I couldn't
> find or build a cross-compiler that would run on my system. But by code
> inspection they shouldn't break with this patch.
> 
> Signed-off-by: Thierry Reding <treding@nvidia.com>

Acked-by: Arnd Bergmann <arnd@arndb.de>

Thanks for doing this!

Not sure how to best merge the series, but for the asm-generic patch,
I'd suggest to keep it together with the follow-on patches in one
branch and merge it either through Russell's arm32 tree or through
Catalin's arm64 tree.

The easiest way would probably be to take patches 1 and 3 for arm64 in
3.17 and merge patch 2 in 3.18, unless Russell wants to see this earlier,
in which case we could have a branch that is shared between arm32 and
arm64.

	Arnd

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 3/3] arm64: Use include/asm-generic/io.h
  2014-07-09 15:11 ` [PATCH 3/3] arm64: " Thierry Reding
@ 2014-07-10 11:00   ` Catalin Marinas
  2014-07-10 13:14     ` Arnd Bergmann
  0 siblings, 1 reply; 11+ messages in thread
From: Catalin Marinas @ 2014-07-10 11:00 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Jul 09, 2014 at 04:11:39PM +0100, Thierry Reding wrote:
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index a497556520d4..a428ac1573e7 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -20,7 +20,6 @@ config ARM64
>  	select GENERIC_CLOCKEVENTS_BROADCAST if SMP
>  	select GENERIC_CPU_AUTOPROBE
>  	select GENERIC_EARLY_IOREMAP
> -	select GENERIC_IOMAP
>  	select GENERIC_IRQ_PROBE
>  	select GENERIC_IRQ_SHOW
>  	select GENERIC_SCHED_CLOCK
> diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h
> index e0ecdcf6632d..00c7f9faf2a3 100644
> --- a/arch/arm64/include/asm/io.h
> +++ b/arch/arm64/include/asm/io.h
[...]
> @@ -235,8 +155,7 @@ extern void __iomem *ioremap_cache(phys_addr_t phys_addr, size_t size);
>  #define ioremap_wc(addr, size)		__ioremap((addr), (size), __pgprot(PROT_NORMAL_NC))
>  #define iounmap				__iounmap
>  
> -#define ARCH_HAS_IOREMAP_WC
> -#include <asm-generic/iomap.h>
> +#include <asm-generic/io.h>

We don't currently have PCIe support in mainline for arm64 but what I
had in mind with the generic iomap is that functions like ioread32_rep
first check whether the address is an IO address or a memory one and
calls the insl or mmio_insl accordingly. With your generic
implementation, this check disappears.

The question is whether this functionality would still be needed.

-- 
Catalin

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 3/3] arm64: Use include/asm-generic/io.h
  2014-07-10 11:00   ` Catalin Marinas
@ 2014-07-10 13:14     ` Arnd Bergmann
  2014-07-11 12:19       ` Catalin Marinas
  0 siblings, 1 reply; 11+ messages in thread
From: Arnd Bergmann @ 2014-07-10 13:14 UTC (permalink / raw)
  To: linux-arm-kernel

On Thursday 10 July 2014, Catalin Marinas wrote:
> > @@ -235,8 +155,7 @@ extern void __iomem *ioremap_cache(phys_addr_t phys_addr, size_t size);
> >  #define ioremap_wc(addr, size)               __ioremap((addr), (size), __pgprot(PROT_NORMAL_NC))
> >  #define iounmap                              __iounmap
> >  
> > -#define ARCH_HAS_IOREMAP_WC
> > -#include <asm-generic/iomap.h>
> > +#include <asm-generic/io.h>
> 
> We don't currently have PCIe support in mainline for arm64 but what I
> had in mind with the generic iomap is that functions like ioread32_rep
> first check whether the address is an IO address or a memory one and
> calls the insl or mmio_insl accordingly. With your generic
> implementation, this check disappears.
> 
> The question is whether this functionality would still be needed.

I think it's much better not to have that check on architectures that have a memory
mapped I/O space like arm64. The main advantage is that ioread32() is just a trivial
alias for readl(). The only reason for needing generic_iomap is architectures that
do something very different for I/O ports.

	Arnd

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 3/3] arm64: Use include/asm-generic/io.h
  2014-07-10 13:14     ` Arnd Bergmann
@ 2014-07-11 12:19       ` Catalin Marinas
  2014-07-11 12:58         ` Arnd Bergmann
  0 siblings, 1 reply; 11+ messages in thread
From: Catalin Marinas @ 2014-07-11 12:19 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Jul 10, 2014 at 02:14:16PM +0100, Arnd Bergmann wrote:
> On Thursday 10 July 2014, Catalin Marinas wrote:
> > > @@ -235,8 +155,7 @@ extern void __iomem *ioremap_cache(phys_addr_t phys_addr, size_t size);
> > >  #define ioremap_wc(addr, size)               __ioremap((addr), (size), __pgprot(PROT_NORMAL_NC))
> > >  #define iounmap                              __iounmap
> > >  
> > > -#define ARCH_HAS_IOREMAP_WC
> > > -#include <asm-generic/iomap.h>
> > > +#include <asm-generic/io.h>
> > 
> > We don't currently have PCIe support in mainline for arm64 but what I
> > had in mind with the generic iomap is that functions like ioread32_rep
> > first check whether the address is an IO address or a memory one and
> > calls the insl or mmio_insl accordingly. With your generic
> > implementation, this check disappears.
> > 
> > The question is whether this functionality would still be needed.
> 
> I think it's much better not to have that check on architectures that have a memory
> mapped I/O space like arm64. The main advantage is that ioread32() is just a trivial
> alias for readl(). The only reason for needing generic_iomap is architectures that
> do something very different for I/O ports.

ioread32() is indeed an alias for readl on arm64 but if the address it
gets as argument looks like an I/O port, it adds PCI_IOBASE (via the inl
macro). This would no longer happen with Thierry's patches.

So I guess that for this patch to work, we also need ioport_map() to
return an address from the PCI_IOBASE range. Should we merge this now as
well:

http://linux-arm.org/git?p=linux-ld.git;a=commitdiff;h=3423064d8e42a38164a8436bcdf7434cf9cd2192

-- 
Catalin

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 3/3] arm64: Use include/asm-generic/io.h
  2014-07-11 12:19       ` Catalin Marinas
@ 2014-07-11 12:58         ` Arnd Bergmann
  2014-07-11 13:01           ` Thierry Reding
  0 siblings, 1 reply; 11+ messages in thread
From: Arnd Bergmann @ 2014-07-11 12:58 UTC (permalink / raw)
  To: linux-arm-kernel

On Friday 11 July 2014, Catalin Marinas wrote:
> ioread32() is indeed an alias for readl on arm64 but if the address it
> gets as argument looks like an I/O port, it adds PCI_IOBASE (via the inl
> macro). This would no longer happen with Thierry's patches.
> 
> So I guess that for this patch to work, we also need ioport_map() to
> return an address from the PCI_IOBASE range. Should we merge this now as
> well:
> 
> http://linux-arm.org/git?p=linux-ld.git;a=commitdiff;h=3423064d8e42a38164a8436bcdf7434cf9cd2192

This is also part of patch 1/3 in Thierry's series.

	Arnd

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 3/3] arm64: Use include/asm-generic/io.h
  2014-07-11 12:58         ` Arnd Bergmann
@ 2014-07-11 13:01           ` Thierry Reding
  2014-07-11 14:00             ` Catalin Marinas
  0 siblings, 1 reply; 11+ messages in thread
From: Thierry Reding @ 2014-07-11 13:01 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Jul 11, 2014 at 02:58:09PM +0200, Arnd Bergmann wrote:
> On Friday 11 July 2014, Catalin Marinas wrote:
> > ioread32() is indeed an alias for readl on arm64 but if the address it
> > gets as argument looks like an I/O port, it adds PCI_IOBASE (via the inl
> > macro). This would no longer happen with Thierry's patches.
> > 
> > So I guess that for this patch to work, we also need ioport_map() to
> > return an address from the PCI_IOBASE range. Should we merge this now as
> > well:
> > 
> > http://linux-arm.org/git?p=linux-ld.git;a=commitdiff;h=3423064d8e42a38164a8436bcdf7434cf9cd2192
> 
> This is also part of patch 1/3 in Thierry's series.

The hunk in my patch 1/3 is missing the "& IO_SPACE_LIMIT", I can respin
and include that.

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140711/d9292bd8/attachment.sig>

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 3/3] arm64: Use include/asm-generic/io.h
  2014-07-11 13:01           ` Thierry Reding
@ 2014-07-11 14:00             ` Catalin Marinas
  0 siblings, 0 replies; 11+ messages in thread
From: Catalin Marinas @ 2014-07-11 14:00 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Jul 11, 2014 at 02:01:59PM +0100, Thierry Reding wrote:
> On Fri, Jul 11, 2014 at 02:58:09PM +0200, Arnd Bergmann wrote:
> > On Friday 11 July 2014, Catalin Marinas wrote:
> > > ioread32() is indeed an alias for readl on arm64 but if the address it
> > > gets as argument looks like an I/O port, it adds PCI_IOBASE (via the inl
> > > macro). This would no longer happen with Thierry's patches.
> > > 
> > > So I guess that for this patch to work, we also need ioport_map() to
> > > return an address from the PCI_IOBASE range. Should we merge this now as
> > > well:
> > > 
> > > http://linux-arm.org/git?p=linux-ld.git;a=commitdiff;h=3423064d8e42a38164a8436bcdf7434cf9cd2192
> > 
> > This is also part of patch 1/3 in Thierry's series.
> 
> The hunk in my patch 1/3 is missing the "& IO_SPACE_LIMIT", I can respin
> and include that.

OK, I missed this part. In which case, the patches look fine:

Acked-by: Catalin Marinas <catalin.marinas@arm.com>

(I'm also happy to merge 1 and 3, whatever you prefer)

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2014-07-11 14:00 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-07-09 15:11 [PATCH 1/3] asm-generic/io.h: Implement generic {read,write}s*() Thierry Reding
2014-07-09 15:11 ` [PATCH 2/3] ARM: Use include/asm-generic/io.h Thierry Reding
2014-07-09 15:11 ` [PATCH 3/3] arm64: " Thierry Reding
2014-07-10 11:00   ` Catalin Marinas
2014-07-10 13:14     ` Arnd Bergmann
2014-07-11 12:19       ` Catalin Marinas
2014-07-11 12:58         ` Arnd Bergmann
2014-07-11 13:01           ` Thierry Reding
2014-07-11 14:00             ` Catalin Marinas
2014-07-09 17:38 ` [PATCH 1/3] asm-generic/io.h: Implement generic {read,write}s*() Sam Ravnborg
2014-07-10 10:38 ` Arnd Bergmann

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).