* [PATCH v2 1/3] asm-generic/io.h: Implement generic {read,write}s*()
@ 2014-07-11 15:31 Thierry Reding
2014-07-11 15:31 ` [PATCH v2 2/3] ARM: Use include/asm-generic/io.h Thierry Reding
` (3 more replies)
0 siblings, 4 replies; 10+ messages in thread
From: Thierry Reding @ 2014-07-11 15:31 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>
---
Changes in v2:
- respect IO_SPACE_LIMIT in ioport_map()
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..32aecbe41188 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 & IO_SPACE_LIMIT);
}
+#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] 10+ messages in thread
* [PATCH v2 2/3] ARM: Use include/asm-generic/io.h
2014-07-11 15:31 [PATCH v2 1/3] asm-generic/io.h: Implement generic {read,write}s*() Thierry Reding
@ 2014-07-11 15:31 ` Thierry Reding
2014-07-11 16:24 ` Catalin Marinas
2014-07-11 15:31 ` [PATCH v2 3/3] arm64: " Thierry Reding
` (2 subsequent siblings)
3 siblings, 1 reply; 10+ messages in thread
From: Thierry Reding @ 2014-07-11 15:31 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] 10+ messages in thread
* [PATCH v2 3/3] arm64: Use include/asm-generic/io.h
2014-07-11 15:31 [PATCH v2 1/3] asm-generic/io.h: Implement generic {read,write}s*() Thierry Reding
2014-07-11 15:31 ` [PATCH v2 2/3] ARM: Use include/asm-generic/io.h Thierry Reding
@ 2014-07-11 15:31 ` Thierry Reding
2014-07-11 16:18 ` [PATCH v2 1/3] asm-generic/io.h: Implement generic {read,write}s*() Catalin Marinas
2014-07-11 21:59 ` [PATCH v2 1/3] asm-generic/io.h: Implement generic {read, write}s*() Stephen Boyd
3 siblings, 0 replies; 10+ messages in thread
From: Thierry Reding @ 2014-07-11 15:31 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.
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
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 02cd76f6d7b4..3fa250534e16 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -21,7 +21,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] 10+ messages in thread
* [PATCH v2 1/3] asm-generic/io.h: Implement generic {read,write}s*()
2014-07-11 15:31 [PATCH v2 1/3] asm-generic/io.h: Implement generic {read,write}s*() Thierry Reding
2014-07-11 15:31 ` [PATCH v2 2/3] ARM: Use include/asm-generic/io.h Thierry Reding
2014-07-11 15:31 ` [PATCH v2 3/3] arm64: " Thierry Reding
@ 2014-07-11 16:18 ` Catalin Marinas
2014-07-11 21:59 ` [PATCH v2 1/3] asm-generic/io.h: Implement generic {read, write}s*() Stephen Boyd
3 siblings, 0 replies; 10+ messages in thread
From: Catalin Marinas @ 2014-07-11 16:18 UTC (permalink / raw)
To: linux-arm-kernel
On Fri, Jul 11, 2014 at 04:31:10PM +0100, 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: Catalin Marinas <catalin.marinas@arm.com>
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v2 2/3] ARM: Use include/asm-generic/io.h
2014-07-11 15:31 ` [PATCH v2 2/3] ARM: Use include/asm-generic/io.h Thierry Reding
@ 2014-07-11 16:24 ` Catalin Marinas
2014-07-12 12:27 ` Arnd Bergmann
0 siblings, 1 reply; 10+ messages in thread
From: Catalin Marinas @ 2014-07-11 16:24 UTC (permalink / raw)
To: linux-arm-kernel
On Fri, Jul 11, 2014 at 04:31:11PM +0100, Thierry Reding wrote:
> 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
[...]
> -#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); })
Aren't you losing the barrier semantics here? The generic iowrite*be()
functions call __raw_write*() directly which don't have a barrier
(write* accessors do).
--
Catalin
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v2 1/3] asm-generic/io.h: Implement generic {read, write}s*()
2014-07-11 15:31 [PATCH v2 1/3] asm-generic/io.h: Implement generic {read,write}s*() Thierry Reding
` (2 preceding siblings ...)
2014-07-11 16:18 ` [PATCH v2 1/3] asm-generic/io.h: Implement generic {read,write}s*() Catalin Marinas
@ 2014-07-11 21:59 ` Stephen Boyd
2014-07-14 9:10 ` [PATCH v2 1/3] asm-generic/io.h: Implement generic {read,write}s*() Thierry Reding
3 siblings, 1 reply; 10+ messages in thread
From: Stephen Boyd @ 2014-07-11 21:59 UTC (permalink / raw)
To: linux-arm-kernel
On 07/11/14 08:31, 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>
There isn't any mention of why we're doing this in the commit text. It
looks like patch 2 and 3 sort of mention why.
I also wonder if it could be explained how this about turn is desired,
given that patch b2656a138ab7 (asm-generic: io: remove {read,write}
string functions, 2012-10-17) did the complete opposite. Can you please
explain?
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v2 2/3] ARM: Use include/asm-generic/io.h
2014-07-11 16:24 ` Catalin Marinas
@ 2014-07-12 12:27 ` Arnd Bergmann
2014-07-12 14:18 ` Catalin Marinas
0 siblings, 1 reply; 10+ messages in thread
From: Arnd Bergmann @ 2014-07-12 12:27 UTC (permalink / raw)
To: linux-arm-kernel
On Friday 11 July 2014, Catalin Marinas wrote:
>
> On Fri, Jul 11, 2014 at 04:31:11PM +0100, Thierry Reding wrote:
> > 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
> [...]
> > -#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); })
>
> Aren't you losing the barrier semantics here? The generic iowrite*be()
> functions call __raw_write*() directly which don't have a barrier
> (write* accessors do).
>
Indeed, sorry for missing this. The generic implementation still makes sense for
include/asm-generic, but arm32 and arm64 must provide their own versions here.
An alternative would be to define
#define iowrite32be(v, p) iowrite32(swab32(v), p)
which is correct but can end up swapping multiple twice.
Arnd
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v2 2/3] ARM: Use include/asm-generic/io.h
2014-07-12 12:27 ` Arnd Bergmann
@ 2014-07-12 14:18 ` Catalin Marinas
0 siblings, 0 replies; 10+ messages in thread
From: Catalin Marinas @ 2014-07-12 14:18 UTC (permalink / raw)
To: linux-arm-kernel
On 12 Jul 2014, at 13:27, Arnd Bergmann <arnd@arndb.de> wrote:
> On Friday 11 July 2014, Catalin Marinas wrote:
>>
>> On Fri, Jul 11, 2014 at 04:31:11PM +0100, Thierry Reding wrote:
>>> 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
>> [...]
>>> -#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); })
>>
>> Aren't you losing the barrier semantics here? The generic iowrite*be()
>> functions call __raw_write*() directly which don't have a barrier
>> (write* accessors do).
>
> Indeed, sorry for missing this. The generic implementation still makes sense for
> include/asm-generic, but arm32 and arm64 must provide their own versions here.
I think this would be the easiest. But the asm-generic/io.h needs some
#ifndef iowrite16be checks.
(in arm64 we missed the iowrite*be barriers completely, so not broken by
this patch; Thierry could update arm64 as well with patch 3/3)
Catalin
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v2 1/3] asm-generic/io.h: Implement generic {read,write}s*()
2014-07-11 21:59 ` [PATCH v2 1/3] asm-generic/io.h: Implement generic {read, write}s*() Stephen Boyd
@ 2014-07-14 9:10 ` Thierry Reding
2014-07-14 17:23 ` [PATCH v2 1/3] asm-generic/io.h: Implement generic {read, write}s*() Stephen Boyd
0 siblings, 1 reply; 10+ messages in thread
From: Thierry Reding @ 2014-07-14 9:10 UTC (permalink / raw)
To: linux-arm-kernel
On Fri, Jul 11, 2014 at 02:59:38PM -0700, Stephen Boyd wrote:
> On 07/11/14 08:31, 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>
>
> There isn't any mention of why we're doing this in the commit text. It
> looks like patch 2 and 3 sort of mention why.
>
> I also wonder if it could be explained how this about turn is desired,
> given that patch b2656a138ab7 (asm-generic: io: remove {read,write}
> string functions, 2012-10-17) did the complete opposite. Can you please
> explain?
The reason behind this was that people have been told to migrate towards
using io{read,write}{8,16,32}_rep() because {read,write}s{b,w,l}() are
not as "portable". The only reason why the aren't portable is because no
generic versions of them existed. That's what this series originally
started out as.
Also, it's somewhat backwards (and inconsistent) to go through the io*()
functions when it's known up front that the device will always only be
memory-mapped and never I/O mapped. So with these patches going forward,
people should be using either {read,write}{,s}{b,w,l}() *or* their
io{read,write}{8,16,32}{,_rep}() counterparts, not mixing them.
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/20140714/d0b35e5a/attachment-0001.sig>
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v2 1/3] asm-generic/io.h: Implement generic {read, write}s*()
2014-07-14 9:10 ` [PATCH v2 1/3] asm-generic/io.h: Implement generic {read,write}s*() Thierry Reding
@ 2014-07-14 17:23 ` Stephen Boyd
0 siblings, 0 replies; 10+ messages in thread
From: Stephen Boyd @ 2014-07-14 17:23 UTC (permalink / raw)
To: linux-arm-kernel
On 07/14/14 02:10, Thierry Reding wrote:
> The reason behind this was that people have been told to migrate towards
> using io{read,write}{8,16,32}_rep() because {read,write}s{b,w,l}() are
> not as "portable". The only reason why the aren't portable is because no
> generic versions of them existed. That's what this series originally
> started out as.
>
> Also, it's somewhat backwards (and inconsistent) to go through the io*()
> functions when it's known up front that the device will always only be
> memory-mapped and never I/O mapped. So with these patches going forward,
> people should be using either {read,write}{,s}{b,w,l}() *or* their
> io{read,write}{8,16,32}{,_rep}() counterparts, not mixing them.
>
Thanks. Can we please have this explanation in the commit text?
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2014-07-14 17:23 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-07-11 15:31 [PATCH v2 1/3] asm-generic/io.h: Implement generic {read,write}s*() Thierry Reding
2014-07-11 15:31 ` [PATCH v2 2/3] ARM: Use include/asm-generic/io.h Thierry Reding
2014-07-11 16:24 ` Catalin Marinas
2014-07-12 12:27 ` Arnd Bergmann
2014-07-12 14:18 ` Catalin Marinas
2014-07-11 15:31 ` [PATCH v2 3/3] arm64: " Thierry Reding
2014-07-11 16:18 ` [PATCH v2 1/3] asm-generic/io.h: Implement generic {read,write}s*() Catalin Marinas
2014-07-11 21:59 ` [PATCH v2 1/3] asm-generic/io.h: Implement generic {read, write}s*() Stephen Boyd
2014-07-14 9:10 ` [PATCH v2 1/3] asm-generic/io.h: Implement generic {read,write}s*() Thierry Reding
2014-07-14 17:23 ` [PATCH v2 1/3] asm-generic/io.h: Implement generic {read, write}s*() Stephen Boyd
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).