Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1674097 > unrolled thread

[PATCH] alpha: provide ioread64 and iowrite64 implementations

Started byRichard Henderson <rth@twiddle.net>
First post2017-06-24 17:20 +0200
Last post2017-06-24 19:20 +0200
Articles 6 — 2 participants

Back to article view | Back to linux.kernel

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  [PATCH] alpha: provide ioread64 and iowrite64 implementations Richard Henderson <rth@twiddle.net> - 2017-06-24 17:20 +0200
    Re: [PATCH] alpha: provide ioread64 and iowrite64 implementations Logan Gunthorpe <logang@deltatee.com> - 2017-06-24 17:30 +0200
      Re: [PATCH] alpha: provide ioread64 and iowrite64 implementations Richard Henderson <rth@twiddle.net> - 2017-06-24 17:30 +0200
        Re: [PATCH] alpha: provide ioread64 and iowrite64 implementations Logan Gunthorpe <logang@deltatee.com> - 2017-06-24 17:40 +0200
          Re: [PATCH] alpha: provide ioread64 and iowrite64 implementations Richard Henderson <rth@twiddle.net> - 2017-06-24 18:20 +0200
            Re: [PATCH] alpha: provide ioread64 and iowrite64 implementations Logan Gunthorpe <logang@deltatee.com> - 2017-06-24 19:20 +0200

#1674097 — [PATCH] alpha: provide ioread64 and iowrite64 implementations

FromRichard Henderson <rth@twiddle.net>
Date2017-06-24 17:20 +0200
Subject[PATCH] alpha: provide ioread64 and iowrite64 implementations
Message-ID<tVV0S-10U-13@gated-at.bofh.it>
All Alpha hosts except for Jensen provide 64-bit I/O operations.

Jensen is EISA only, so there ought not be any devices that even
attempt such operations.  But just in case, use 2 32-bit operations.

Cc: Logan Gunthorpe <logang@deltatee.com>
Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
Cc: Matt Turner <mattst88@gmail.com>
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 arch/alpha/include/asm/core_apecs.h  | 16 ++++++++++++++++
 arch/alpha/include/asm/core_cia.h    | 16 ++++++++++++++++
 arch/alpha/include/asm/core_lca.h    | 16 ++++++++++++++++
 arch/alpha/include/asm/core_mcpcia.h | 21 +++++++++++++++++++++
 arch/alpha/include/asm/core_t2.h     | 24 +++++++++++++++++++-----
 arch/alpha/include/asm/io.h          | 27 +++++++++++++++++++++++++++
 arch/alpha/include/asm/io_trivial.h  | 12 ++++++++++++
 arch/alpha/include/asm/jensen.h      | 32 +++++++++++++++++++++++++++-----
 arch/alpha/include/asm/machvec.h     |  2 ++
 arch/alpha/kernel/io.c               | 27 +++++++++++++++++++++++++++
 arch/alpha/kernel/machvec_impl.h     |  2 ++
 11 files changed, 185 insertions(+), 10 deletions(-)

diff --git a/arch/alpha/include/asm/core_apecs.h b/arch/alpha/include/asm/core_apecs.h
index 6785ff7..7e2ff13 100644
--- a/arch/alpha/include/asm/core_apecs.h
+++ b/arch/alpha/include/asm/core_apecs.h
@@ -471,6 +471,22 @@ __EXTERN_INLINE void apecs_iowrite32(u32 b, void __iomem *xaddr)
 	*(vuip)addr = b;
 }
 
+__EXTERN_INLINE u64 apecs_ioread64(void __iomem *xaddr)
+{
+	unsigned long addr = (unsigned long) xaddr;
+	if (addr < APECS_DENSE_MEM)
+		addr = ((addr - APECS_IO) << 5) + APECS_IO + 0x78;
+	return *(vulp)addr;
+}
+
+__EXTERN_INLINE void apecs_iowrite64(u64 b, void __iomem *xaddr)
+{
+	unsigned long addr = (unsigned long) xaddr;
+	if (addr < APECS_DENSE_MEM)
+		addr = ((addr - APECS_IO) << 5) + APECS_IO + 0x78;
+	*(vulp)addr = b;
+}
+
 __EXTERN_INLINE void __iomem *apecs_ioportmap(unsigned long addr)
 {
 	return (void __iomem *)(addr + APECS_IO);
diff --git a/arch/alpha/include/asm/core_cia.h b/arch/alpha/include/asm/core_cia.h
index 9e0516c..54792b3 100644
--- a/arch/alpha/include/asm/core_cia.h
+++ b/arch/alpha/include/asm/core_cia.h
@@ -419,6 +419,22 @@ __EXTERN_INLINE void cia_iowrite32(u32 b, void __iomem *xaddr)
 	*(vuip)addr = b;
 }
 
+__EXTERN_INLINE u64 cia_ioread64(void __iomem *xaddr)
+{
+	unsigned long addr = (unsigned long) xaddr;
+	if (addr < CIA_DENSE_MEM)
+		addr = ((addr - CIA_IO) << 5) + CIA_IO + 0x78;
+	return *(vulp)addr;
+}
+
+__EXTERN_INLINE void cia_iowrite64(u64 b, void __iomem *xaddr)
+{
+	unsigned long addr = (unsigned long) xaddr;
+	if (addr < CIA_DENSE_MEM)
+		addr = ((addr - CIA_IO) << 5) + CIA_IO + 0x78;
+	*(vulp)addr = b;
+}
+
 __EXTERN_INLINE void __iomem *cia_ioportmap(unsigned long addr)
 {
 	return (void __iomem *)(addr + CIA_IO);
diff --git a/arch/alpha/include/asm/core_lca.h b/arch/alpha/include/asm/core_lca.h
index 8ee6c51..b8e43cd 100644
--- a/arch/alpha/include/asm/core_lca.h
+++ b/arch/alpha/include/asm/core_lca.h
@@ -317,6 +317,22 @@ __EXTERN_INLINE void lca_iowrite32(u32 b, void __iomem *xaddr)
 	*(vuip)addr = b;
 }
 
+__EXTERN_INLINE u64 lca_ioread64(void __iomem *xaddr)
+{
+	unsigned long addr = (unsigned long) xaddr;
+	if (addr < LCA_DENSE_MEM)
+		addr = ((addr - LCA_IO) << 5) + LCA_IO + 0x78;
+	return *(vulp)addr;
+}
+
+__EXTERN_INLINE void lca_iowrite64(u64 b, void __iomem *xaddr)
+{
+	unsigned long addr = (unsigned long) xaddr;
+	if (addr < LCA_DENSE_MEM)
+		addr = ((addr - LCA_IO) << 5) + LCA_IO + 0x78;
+	*(vulp)addr = b;
+}
+
 __EXTERN_INLINE void __iomem *lca_ioportmap(unsigned long addr)
 {
 	return (void __iomem *)(addr + LCA_IO);
diff --git a/arch/alpha/include/asm/core_mcpcia.h b/arch/alpha/include/asm/core_mcpcia.h
index ad44bef..e4d9139 100644
--- a/arch/alpha/include/asm/core_mcpcia.h
+++ b/arch/alpha/include/asm/core_mcpcia.h
@@ -247,6 +247,7 @@ struct el_MCPCIA_uncorrected_frame_mcheck {
 
 #define vip	volatile int __force *
 #define vuip	volatile unsigned int __force *
+#define vulp	volatile unsigned long __force *
 
 #ifndef MCPCIA_ONE_HAE_WINDOW
 #define MCPCIA_FROB_MMIO						\
@@ -334,6 +335,25 @@ __EXTERN_INLINE void mcpcia_iowrite32(u32 b, void __iomem *xaddr)
 	*(vuip)addr = b;
 }
 
+__EXTERN_INLINE u64 mcpcia_ioread64(void __iomem *xaddr)
+{
+	unsigned long addr = (unsigned long)xaddr;
+
+	if (!__mcpcia_is_mmio(addr))
+		addr = ((addr & 0xffff) << 5) + (addr & ~0xfffful) + 0x78;
+
+	return *(vulp)addr;
+}
+
+__EXTERN_INLINE void mcpcia_iowrite64(u64 b, void __iomem *xaddr)
+{
+	unsigned long addr = (unsigned long)xaddr;
+
+	if (!__mcpcia_is_mmio(addr))
+		addr = ((addr & 0xffff) << 5) + (addr & ~0xfffful) + 0x78;
+
+	*(vulp)addr = b;
+}
 
 __EXTERN_INLINE void __iomem *mcpcia_ioportmap(unsigned long addr)
 {
@@ -361,6 +381,7 @@ __EXTERN_INLINE int mcpcia_is_mmio(const volatile void __iomem *xaddr)
 
 #undef vip
 #undef vuip
+#undef vulp
 
 #undef __IO_PREFIX
 #define __IO_PREFIX		mcpcia
diff --git a/arch/alpha/include/asm/core_t2.h b/arch/alpha/include/asm/core_t2.h
index ade9d92..cb3467d 100644
--- a/arch/alpha/include/asm/core_t2.h
+++ b/arch/alpha/include/asm/core_t2.h
@@ -359,6 +359,7 @@ struct el_t2_frame_corrected {
 
 #define vip	volatile int *
 #define vuip	volatile unsigned int *
+#define vulp	volatile unsigned long *
 
 extern inline u8 t2_inb(unsigned long addr)
 {
@@ -401,6 +402,17 @@ extern inline void t2_outl(u32 b, unsigned long addr)
 	mb();
 }
 
+extern inline u64 t2_inq(unsigned long addr)
+{
+	return *(vulp) ((addr << 5) + T2_IO + 0x78);
+}
+
+extern inline void t2_outq(u64 b, unsigned long addr)
+{
+	*(vulp) ((addr << 5) + T2_IO + 0x78) = b;
+	mb();
+}
+
 
 /*
  * Memory functions.
@@ -570,8 +582,8 @@ __EXTERN_INLINE int t2_is_mmio(const volatile void __iomem *addr)
 /* New-style ioread interface.  The mmio routines are so ugly for T2 that
    it doesn't make sense to merge the pio and mmio routines.  */
 
-#define IOPORT(OS, NS)							\
-__EXTERN_INLINE unsigned int t2_ioread##NS(void __iomem *xaddr)		\
+#define IOPORT(OS, NS, RT)						\
+__EXTERN_INLINE RT t2_ioread##NS(void __iomem *xaddr)		\
 {									\
 	if (t2_is_mmio(xaddr))						\
 		return t2_read##OS(xaddr);				\
@@ -586,14 +598,16 @@ __EXTERN_INLINE void t2_iowrite##NS(u##NS b, void __iomem *xaddr)	\
 		t2_out##OS(b, (unsigned long)xaddr - T2_IO);		\
 }
 
-IOPORT(b, 8)
-IOPORT(w, 16)
-IOPORT(l, 32)
+IOPORT(b, 8, unsigned int)
+IOPORT(w, 16, unsigned int)
+IOPORT(l, 32, unsigned int)
+IOPORT(q, 64, u64)
 
 #undef IOPORT
 
 #undef vip
 #undef vuip
+#undef vulp
 
 #undef __IO_PREFIX
 #define __IO_PREFIX		t2
diff --git a/arch/alpha/include/asm/io.h b/arch/alpha/include/asm/io.h
index ff40491..16426e8 100644
--- a/arch/alpha/include/asm/io.h
+++ b/arch/alpha/include/asm/io.h
@@ -158,6 +158,7 @@ static inline void generic_##NAME(TYPE b, QUAL void __iomem *addr)	\
 REMAP1(unsigned int, ioread8, /**/)
 REMAP1(unsigned int, ioread16, /**/)
 REMAP1(unsigned int, ioread32, /**/)
+REMAP1(u64, ioread64, /**/)
 REMAP1(u8, readb, const volatile)
 REMAP1(u16, readw, const volatile)
 REMAP1(u32, readl, const volatile)
@@ -166,6 +167,7 @@ REMAP1(u64, readq, const volatile)
 REMAP2(u8, iowrite8, /**/)
 REMAP2(u16, iowrite16, /**/)
 REMAP2(u32, iowrite32, /**/)
+REMAP2(u64, iowrite64, /**/)
 REMAP2(u8, writeb, volatile)
 REMAP2(u16, writew, volatile)
 REMAP2(u32, writel, volatile)
@@ -384,6 +386,19 @@ extern inline void iowrite32(u32 b, void __iomem *addr)
 	mb();
 }
 
+extern inline u64 ioread64(void __iomem *addr)
+{
+	unsigned int ret = IO_CONCAT(__IO_PREFIX,ioread64)(addr);
+	mb();
+	return ret;
+}
+
+extern inline void iowrite64(u64 b, void __iomem *addr)
+{
+	IO_CONCAT(__IO_PREFIX,iowrite64)(b, addr);
+	mb();
+}
+
 extern inline u32 inl(unsigned long port)
 {
 	return ioread32(ioport_map(port, 4));
@@ -393,6 +408,16 @@ extern inline void outl(u32 b, unsigned long port)
 {
 	iowrite32(b, ioport_map(port, 4));
 }
+
+extern inline u64 inq(unsigned long port)
+{
+	return ioread64(ioport_map(port, 8));
+}
+
+extern inline void outq(u64 b, unsigned long port)
+{
+	iowrite64(b, ioport_map(port, 8));
+}
 #endif
 
 #if IO_CONCAT(__IO_PREFIX,trivial_rw_bw) == 1
@@ -493,8 +518,10 @@ extern inline void writeq(u64 b, volatile void __iomem *addr)
 
 #define ioread16be(p) be16_to_cpu(ioread16(p))
 #define ioread32be(p) be32_to_cpu(ioread32(p))
+#define ioread64be(p) be64_to_cpu(ioread64(p))
 #define iowrite16be(v,p) iowrite16(cpu_to_be16(v), (p))
 #define iowrite32be(v,p) iowrite32(cpu_to_be32(v), (p))
+#define iowrite64be(v,p) iowrite64(cpu_to_be64(v), (p))
 
 #define inb_p		inb
 #define inw_p		inw
diff --git a/arch/alpha/include/asm/io_trivial.h b/arch/alpha/include/asm/io_trivial.h
index 1c77f10..ae97730 100644
--- a/arch/alpha/include/asm/io_trivial.h
+++ b/arch/alpha/include/asm/io_trivial.h
@@ -37,11 +37,23 @@ IO_CONCAT(__IO_PREFIX,ioread32)(void __iomem *a)
 	return *(volatile u32 __force *)a;
 }
 
+__EXTERN_INLINE u64
+IO_CONCAT(__IO_PREFIX,ioread64)(void __iomem *a)
+{
+	return *(volatile u64 __force *)a;
+}
+
 __EXTERN_INLINE void
 IO_CONCAT(__IO_PREFIX,iowrite32)(u32 b, void __iomem *a)
 {
 	*(volatile u32 __force *)a = b;
 }
+
+__EXTERN_INLINE void
+IO_CONCAT(__IO_PREFIX,iowrite64)(u64 b, void __iomem *a)
+{
+	*(volatile u64 __force *)a = b;
+}
 #endif
 
 #if IO_CONCAT(__IO_PREFIX,trivial_rw_bw) == 1
diff --git a/arch/alpha/include/asm/jensen.h b/arch/alpha/include/asm/jensen.h
index 964b06e..7e945cf 100644
--- a/arch/alpha/include/asm/jensen.h
+++ b/arch/alpha/include/asm/jensen.h
@@ -182,6 +182,17 @@ __EXTERN_INLINE u32 jensen_inl(unsigned long addr)
 	return *(vuip) ((addr << 7) + EISA_IO + 0x60);
 }
 
+__EXTERN_INLINE u64 jensen_inq(unsigned long addr)
+{
+	unsigned long ioaddr = (addr << 7) + EISA_IO + 0x60;
+	unsigned long l, h;
+
+	jensen_set_hae(0);
+	l = *(vuip)ioaddr;
+	h = *(vuip)(ioaddr + (4 << 7));
+	return h << 32 | l;
+}
+
 __EXTERN_INLINE void jensen_outw(u16 b, unsigned long addr)
 {
 	jensen_set_hae(0);
@@ -196,6 +207,16 @@ __EXTERN_INLINE void jensen_outl(u32 b, unsigned long addr)
 	mb();
 }
 
+__EXTERN_INLINE void jensen_outq(u64 b, unsigned long addr)
+{
+	unsigned long ioaddr = (addr << 7) + EISA_IO + 0x60;
+
+	jensen_set_hae(0);
+	*(vuip)ioaddr = b;
+	*(vuip)(ioaddr + (4 << 7)) = b >> 32;
+	mb();
+}
+
 /*
  * Memory functions.
  */
@@ -303,8 +324,8 @@ __EXTERN_INLINE int jensen_is_mmio(const volatile void __iomem *addr)
 /* New-style ioread interface.  All the routines are so ugly for Jensen
    that it doesn't make sense to merge them.  */
 
-#define IOPORT(OS, NS)							\
-__EXTERN_INLINE unsigned int jensen_ioread##NS(void __iomem *xaddr)	\
+#define IOPORT(OS, NS, RT)						\
+__EXTERN_INLINE RT jensen_ioread##NS(void __iomem *xaddr)		\
 {									\
 	if (jensen_is_mmio(xaddr))					\
 		return jensen_read##OS(xaddr - 0x100000000ul);		\
@@ -319,9 +340,10 @@ __EXTERN_INLINE void jensen_iowrite##NS(u##NS b, void __iomem *xaddr)	\
 		jensen_out##OS(b, (unsigned long)xaddr);		\
 }
 
-IOPORT(b, 8)
-IOPORT(w, 16)
-IOPORT(l, 32)
+IOPORT(b, 8, unsigned int)
+IOPORT(w, 16, unsigned int)
+IOPORT(l, 32, unsigned int)
+IOPORT(q, 64, u64)
 
 #undef IOPORT
 
diff --git a/arch/alpha/include/asm/machvec.h b/arch/alpha/include/asm/machvec.h
index 75cb364..c037c7b 100644
--- a/arch/alpha/include/asm/machvec.h
+++ b/arch/alpha/include/asm/machvec.h
@@ -48,10 +48,12 @@ struct alpha_machine_vector
 	unsigned int (*mv_ioread8)(void __iomem *);
 	unsigned int (*mv_ioread16)(void __iomem *);
 	unsigned int (*mv_ioread32)(void __iomem *);
+	u64 (*mv_ioread64)(void __iomem *);
 
 	void (*mv_iowrite8)(u8, void __iomem *);
 	void (*mv_iowrite16)(u16, void __iomem *);
 	void (*mv_iowrite32)(u32, void __iomem *);
+	void (*mv_iowrite64)(u64, void __iomem *);
 
 	u8 (*mv_readb)(const volatile void __iomem *);
 	u16 (*mv_readw)(const volatile void __iomem *);
diff --git a/arch/alpha/kernel/io.c b/arch/alpha/kernel/io.c
index 19c5875..d36146f 100644
--- a/arch/alpha/kernel/io.c
+++ b/arch/alpha/kernel/io.c
@@ -34,6 +34,13 @@ unsigned int ioread32(void __iomem *addr)
 	return ret;
 }
 
+u64 ioread64(void __iomem *addr)
+{
+	u64 ret = IO_CONCAT(__IO_PREFIX,ioread64)(addr);
+	mb();
+	return ret;
+}
+
 void iowrite8(u8 b, void __iomem *addr)
 {
 	IO_CONCAT(__IO_PREFIX,iowrite8)(b, addr);
@@ -52,12 +59,20 @@ void iowrite32(u32 b, void __iomem *addr)
 	mb();
 }
 
+void iowrite64(u64 b, void __iomem *addr)
+{
+	IO_CONCAT(__IO_PREFIX,iowrite64)(b, addr);
+	mb();
+}
+
 EXPORT_SYMBOL(ioread8);
 EXPORT_SYMBOL(ioread16);
 EXPORT_SYMBOL(ioread32);
+EXPORT_SYMBOL(ioread64);
 EXPORT_SYMBOL(iowrite8);
 EXPORT_SYMBOL(iowrite16);
 EXPORT_SYMBOL(iowrite32);
+EXPORT_SYMBOL(iowrite64);
 
 u8 inb(unsigned long port)
 {
@@ -74,6 +89,11 @@ u32 inl(unsigned long port)
 	return ioread32(ioport_map(port, 4));
 }
 
+u64 inq(unsigned long port)
+{
+	return ioread64(ioport_map(port, 8));
+}
+
 void outb(u8 b, unsigned long port)
 {
 	iowrite8(b, ioport_map(port, 1));
@@ -89,12 +109,19 @@ void outl(u32 b, unsigned long port)
 	iowrite32(b, ioport_map(port, 4));
 }
 
+void outq(u64 b, unsigned long port)
+{
+	iowrite64(b, ioport_map(port, 8));
+}
+
 EXPORT_SYMBOL(inb);
 EXPORT_SYMBOL(inw);
 EXPORT_SYMBOL(inl);
+EXPORT_SYMBOL(inq);
 EXPORT_SYMBOL(outb);
 EXPORT_SYMBOL(outw);
 EXPORT_SYMBOL(outl);
+EXPORT_SYMBOL(outq);
 
 u8 __raw_readb(const volatile void __iomem *addr)
 {
diff --git a/arch/alpha/kernel/machvec_impl.h b/arch/alpha/kernel/machvec_impl.h
index b7d6960..9b37e19 100644
--- a/arch/alpha/kernel/machvec_impl.h
+++ b/arch/alpha/kernel/machvec_impl.h
@@ -79,9 +79,11 @@
 	.mv_ioread8 =		CAT(low,_ioread8),			\
 	.mv_ioread16 =		CAT(low,_ioread16),			\
 	.mv_ioread32 =		CAT(low,_ioread32),			\
+	.mv_ioread64 =		CAT(low,_ioread64),			\
 	.mv_iowrite8 =		CAT(low,_iowrite8),			\
 	.mv_iowrite16 =		CAT(low,_iowrite16),			\
 	.mv_iowrite32 =		CAT(low,_iowrite32),			\
+	.mv_iowrite64 =		CAT(low,_iowrite64),			\
 	.mv_readb =		CAT(low,_readb),			\
 	.mv_readw =		CAT(low,_readw),			\
 	.mv_readl =		CAT(low,_readl),			\
-- 
2.9.4

[toc] | [next] | [standalone]


#1674098

FromLogan Gunthorpe <logang@deltatee.com>
Date2017-06-24 17:30 +0200
Message-ID<tVVax-141-3@gated-at.bofh.it>
In reply to#1674097
Hey,

On 24/06/17 09:13 AM, Richard Henderson wrote:
> All Alpha hosts except for Jensen provide 64-bit I/O operations.
> 
> Jensen is EISA only, so there ought not be any devices that even
> attempt such operations.  But just in case, use 2 32-bit operations.

Thanks for this, Richard.

However, I was recently enlightened by the existence of the
linux/io-64-nonatomic* headers. This is where the 2 32-bit operation
functions belong. So you should probably remove them from this patch and
let drivers that need them just include those headers.

Logan

> Cc: Logan Gunthorpe <logang@deltatee.com>
> Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
> Cc: Matt Turner <mattst88@gmail.com>
> Signed-off-by: Richard Henderson <rth@twiddle.net>
> ---
>  arch/alpha/include/asm/core_apecs.h  | 16 ++++++++++++++++
>  arch/alpha/include/asm/core_cia.h    | 16 ++++++++++++++++
>  arch/alpha/include/asm/core_lca.h    | 16 ++++++++++++++++
>  arch/alpha/include/asm/core_mcpcia.h | 21 +++++++++++++++++++++
>  arch/alpha/include/asm/core_t2.h     | 24 +++++++++++++++++++-----
>  arch/alpha/include/asm/io.h          | 27 +++++++++++++++++++++++++++
>  arch/alpha/include/asm/io_trivial.h  | 12 ++++++++++++
>  arch/alpha/include/asm/jensen.h      | 32 +++++++++++++++++++++++++++-----
>  arch/alpha/include/asm/machvec.h     |  2 ++
>  arch/alpha/kernel/io.c               | 27 +++++++++++++++++++++++++++
>  arch/alpha/kernel/machvec_impl.h     |  2 ++
>  11 files changed, 185 insertions(+), 10 deletions(-)
> 
> diff --git a/arch/alpha/include/asm/core_apecs.h b/arch/alpha/include/asm/core_apecs.h
> index 6785ff7..7e2ff13 100644
> --- a/arch/alpha/include/asm/core_apecs.h
> +++ b/arch/alpha/include/asm/core_apecs.h
> @@ -471,6 +471,22 @@ __EXTERN_INLINE void apecs_iowrite32(u32 b, void __iomem *xaddr)
>  	*(vuip)addr = b;
>  }
>  
> +__EXTERN_INLINE u64 apecs_ioread64(void __iomem *xaddr)
> +{
> +	unsigned long addr = (unsigned long) xaddr;
> +	if (addr < APECS_DENSE_MEM)
> +		addr = ((addr - APECS_IO) << 5) + APECS_IO + 0x78;
> +	return *(vulp)addr;
> +}
> +
> +__EXTERN_INLINE void apecs_iowrite64(u64 b, void __iomem *xaddr)
> +{
> +	unsigned long addr = (unsigned long) xaddr;
> +	if (addr < APECS_DENSE_MEM)
> +		addr = ((addr - APECS_IO) << 5) + APECS_IO + 0x78;
> +	*(vulp)addr = b;
> +}
> +
>  __EXTERN_INLINE void __iomem *apecs_ioportmap(unsigned long addr)
>  {
>  	return (void __iomem *)(addr + APECS_IO);
> diff --git a/arch/alpha/include/asm/core_cia.h b/arch/alpha/include/asm/core_cia.h
> index 9e0516c..54792b3 100644
> --- a/arch/alpha/include/asm/core_cia.h
> +++ b/arch/alpha/include/asm/core_cia.h
> @@ -419,6 +419,22 @@ __EXTERN_INLINE void cia_iowrite32(u32 b, void __iomem *xaddr)
>  	*(vuip)addr = b;
>  }
>  
> +__EXTERN_INLINE u64 cia_ioread64(void __iomem *xaddr)
> +{
> +	unsigned long addr = (unsigned long) xaddr;
> +	if (addr < CIA_DENSE_MEM)
> +		addr = ((addr - CIA_IO) << 5) + CIA_IO + 0x78;
> +	return *(vulp)addr;
> +}
> +
> +__EXTERN_INLINE void cia_iowrite64(u64 b, void __iomem *xaddr)
> +{
> +	unsigned long addr = (unsigned long) xaddr;
> +	if (addr < CIA_DENSE_MEM)
> +		addr = ((addr - CIA_IO) << 5) + CIA_IO + 0x78;
> +	*(vulp)addr = b;
> +}
> +
>  __EXTERN_INLINE void __iomem *cia_ioportmap(unsigned long addr)
>  {
>  	return (void __iomem *)(addr + CIA_IO);
> diff --git a/arch/alpha/include/asm/core_lca.h b/arch/alpha/include/asm/core_lca.h
> index 8ee6c51..b8e43cd 100644
> --- a/arch/alpha/include/asm/core_lca.h
> +++ b/arch/alpha/include/asm/core_lca.h
> @@ -317,6 +317,22 @@ __EXTERN_INLINE void lca_iowrite32(u32 b, void __iomem *xaddr)
>  	*(vuip)addr = b;
>  }
>  
> +__EXTERN_INLINE u64 lca_ioread64(void __iomem *xaddr)
> +{
> +	unsigned long addr = (unsigned long) xaddr;
> +	if (addr < LCA_DENSE_MEM)
> +		addr = ((addr - LCA_IO) << 5) + LCA_IO + 0x78;
> +	return *(vulp)addr;
> +}
> +
> +__EXTERN_INLINE void lca_iowrite64(u64 b, void __iomem *xaddr)
> +{
> +	unsigned long addr = (unsigned long) xaddr;
> +	if (addr < LCA_DENSE_MEM)
> +		addr = ((addr - LCA_IO) << 5) + LCA_IO + 0x78;
> +	*(vulp)addr = b;
> +}
> +
>  __EXTERN_INLINE void __iomem *lca_ioportmap(unsigned long addr)
>  {
>  	return (void __iomem *)(addr + LCA_IO);
> diff --git a/arch/alpha/include/asm/core_mcpcia.h b/arch/alpha/include/asm/core_mcpcia.h
> index ad44bef..e4d9139 100644
> --- a/arch/alpha/include/asm/core_mcpcia.h
> +++ b/arch/alpha/include/asm/core_mcpcia.h
> @@ -247,6 +247,7 @@ struct el_MCPCIA_uncorrected_frame_mcheck {
>  
>  #define vip	volatile int __force *
>  #define vuip	volatile unsigned int __force *
> +#define vulp	volatile unsigned long __force *
>  
>  #ifndef MCPCIA_ONE_HAE_WINDOW
>  #define MCPCIA_FROB_MMIO						\
> @@ -334,6 +335,25 @@ __EXTERN_INLINE void mcpcia_iowrite32(u32 b, void __iomem *xaddr)
>  	*(vuip)addr = b;
>  }
>  
> +__EXTERN_INLINE u64 mcpcia_ioread64(void __iomem *xaddr)
> +{
> +	unsigned long addr = (unsigned long)xaddr;
> +
> +	if (!__mcpcia_is_mmio(addr))
> +		addr = ((addr & 0xffff) << 5) + (addr & ~0xfffful) + 0x78;
> +
> +	return *(vulp)addr;
> +}
> +
> +__EXTERN_INLINE void mcpcia_iowrite64(u64 b, void __iomem *xaddr)
> +{
> +	unsigned long addr = (unsigned long)xaddr;
> +
> +	if (!__mcpcia_is_mmio(addr))
> +		addr = ((addr & 0xffff) << 5) + (addr & ~0xfffful) + 0x78;
> +
> +	*(vulp)addr = b;
> +}
>  
>  __EXTERN_INLINE void __iomem *mcpcia_ioportmap(unsigned long addr)
>  {
> @@ -361,6 +381,7 @@ __EXTERN_INLINE int mcpcia_is_mmio(const volatile void __iomem *xaddr)
>  
>  #undef vip
>  #undef vuip
> +#undef vulp
>  
>  #undef __IO_PREFIX
>  #define __IO_PREFIX		mcpcia
> diff --git a/arch/alpha/include/asm/core_t2.h b/arch/alpha/include/asm/core_t2.h
> index ade9d92..cb3467d 100644
> --- a/arch/alpha/include/asm/core_t2.h
> +++ b/arch/alpha/include/asm/core_t2.h
> @@ -359,6 +359,7 @@ struct el_t2_frame_corrected {
>  
>  #define vip	volatile int *
>  #define vuip	volatile unsigned int *
> +#define vulp	volatile unsigned long *
>  
>  extern inline u8 t2_inb(unsigned long addr)
>  {
> @@ -401,6 +402,17 @@ extern inline void t2_outl(u32 b, unsigned long addr)
>  	mb();
>  }
>  
> +extern inline u64 t2_inq(unsigned long addr)
> +{
> +	return *(vulp) ((addr << 5) + T2_IO + 0x78);
> +}
> +
> +extern inline void t2_outq(u64 b, unsigned long addr)
> +{
> +	*(vulp) ((addr << 5) + T2_IO + 0x78) = b;
> +	mb();
> +}
> +
>  
>  /*
>   * Memory functions.
> @@ -570,8 +582,8 @@ __EXTERN_INLINE int t2_is_mmio(const volatile void __iomem *addr)
>  /* New-style ioread interface.  The mmio routines are so ugly for T2 that
>     it doesn't make sense to merge the pio and mmio routines.  */
>  
> -#define IOPORT(OS, NS)							\
> -__EXTERN_INLINE unsigned int t2_ioread##NS(void __iomem *xaddr)		\
> +#define IOPORT(OS, NS, RT)						\
> +__EXTERN_INLINE RT t2_ioread##NS(void __iomem *xaddr)		\
>  {									\
>  	if (t2_is_mmio(xaddr))						\
>  		return t2_read##OS(xaddr);				\
> @@ -586,14 +598,16 @@ __EXTERN_INLINE void t2_iowrite##NS(u##NS b, void __iomem *xaddr)	\
>  		t2_out##OS(b, (unsigned long)xaddr - T2_IO);		\
>  }
>  
> -IOPORT(b, 8)
> -IOPORT(w, 16)
> -IOPORT(l, 32)
> +IOPORT(b, 8, unsigned int)
> +IOPORT(w, 16, unsigned int)
> +IOPORT(l, 32, unsigned int)
> +IOPORT(q, 64, u64)
>  
>  #undef IOPORT
>  
>  #undef vip
>  #undef vuip
> +#undef vulp
>  
>  #undef __IO_PREFIX
>  #define __IO_PREFIX		t2
> diff --git a/arch/alpha/include/asm/io.h b/arch/alpha/include/asm/io.h
> index ff40491..16426e8 100644
> --- a/arch/alpha/include/asm/io.h
> +++ b/arch/alpha/include/asm/io.h
> @@ -158,6 +158,7 @@ static inline void generic_##NAME(TYPE b, QUAL void __iomem *addr)	\
>  REMAP1(unsigned int, ioread8, /**/)
>  REMAP1(unsigned int, ioread16, /**/)
>  REMAP1(unsigned int, ioread32, /**/)
> +REMAP1(u64, ioread64, /**/)
>  REMAP1(u8, readb, const volatile)
>  REMAP1(u16, readw, const volatile)
>  REMAP1(u32, readl, const volatile)
> @@ -166,6 +167,7 @@ REMAP1(u64, readq, const volatile)
>  REMAP2(u8, iowrite8, /**/)
>  REMAP2(u16, iowrite16, /**/)
>  REMAP2(u32, iowrite32, /**/)
> +REMAP2(u64, iowrite64, /**/)
>  REMAP2(u8, writeb, volatile)
>  REMAP2(u16, writew, volatile)
>  REMAP2(u32, writel, volatile)
> @@ -384,6 +386,19 @@ extern inline void iowrite32(u32 b, void __iomem *addr)
>  	mb();
>  }
>  
> +extern inline u64 ioread64(void __iomem *addr)
> +{
> +	unsigned int ret = IO_CONCAT(__IO_PREFIX,ioread64)(addr);
> +	mb();
> +	return ret;
> +}
> +
> +extern inline void iowrite64(u64 b, void __iomem *addr)
> +{
> +	IO_CONCAT(__IO_PREFIX,iowrite64)(b, addr);
> +	mb();
> +}
> +
>  extern inline u32 inl(unsigned long port)
>  {
>  	return ioread32(ioport_map(port, 4));
> @@ -393,6 +408,16 @@ extern inline void outl(u32 b, unsigned long port)
>  {
>  	iowrite32(b, ioport_map(port, 4));
>  }
> +
> +extern inline u64 inq(unsigned long port)
> +{
> +	return ioread64(ioport_map(port, 8));
> +}
> +
> +extern inline void outq(u64 b, unsigned long port)
> +{
> +	iowrite64(b, ioport_map(port, 8));
> +}
>  #endif
>  
>  #if IO_CONCAT(__IO_PREFIX,trivial_rw_bw) == 1
> @@ -493,8 +518,10 @@ extern inline void writeq(u64 b, volatile void __iomem *addr)
>  
>  #define ioread16be(p) be16_to_cpu(ioread16(p))
>  #define ioread32be(p) be32_to_cpu(ioread32(p))
> +#define ioread64be(p) be64_to_cpu(ioread64(p))
>  #define iowrite16be(v,p) iowrite16(cpu_to_be16(v), (p))
>  #define iowrite32be(v,p) iowrite32(cpu_to_be32(v), (p))
> +#define iowrite64be(v,p) iowrite64(cpu_to_be64(v), (p))
>  
>  #define inb_p		inb
>  #define inw_p		inw
> diff --git a/arch/alpha/include/asm/io_trivial.h b/arch/alpha/include/asm/io_trivial.h
> index 1c77f10..ae97730 100644
> --- a/arch/alpha/include/asm/io_trivial.h
> +++ b/arch/alpha/include/asm/io_trivial.h
> @@ -37,11 +37,23 @@ IO_CONCAT(__IO_PREFIX,ioread32)(void __iomem *a)
>  	return *(volatile u32 __force *)a;
>  }
>  
> +__EXTERN_INLINE u64
> +IO_CONCAT(__IO_PREFIX,ioread64)(void __iomem *a)
> +{
> +	return *(volatile u64 __force *)a;
> +}
> +
>  __EXTERN_INLINE void
>  IO_CONCAT(__IO_PREFIX,iowrite32)(u32 b, void __iomem *a)
>  {
>  	*(volatile u32 __force *)a = b;
>  }
> +
> +__EXTERN_INLINE void
> +IO_CONCAT(__IO_PREFIX,iowrite64)(u64 b, void __iomem *a)
> +{
> +	*(volatile u64 __force *)a = b;
> +}
>  #endif
>  
>  #if IO_CONCAT(__IO_PREFIX,trivial_rw_bw) == 1
> diff --git a/arch/alpha/include/asm/jensen.h b/arch/alpha/include/asm/jensen.h
> index 964b06e..7e945cf 100644
> --- a/arch/alpha/include/asm/jensen.h
> +++ b/arch/alpha/include/asm/jensen.h
> @@ -182,6 +182,17 @@ __EXTERN_INLINE u32 jensen_inl(unsigned long addr)
>  	return *(vuip) ((addr << 7) + EISA_IO + 0x60);
>  }
>  
> +__EXTERN_INLINE u64 jensen_inq(unsigned long addr)
> +{
> +	unsigned long ioaddr = (addr << 7) + EISA_IO + 0x60;
> +	unsigned long l, h;
> +
> +	jensen_set_hae(0);
> +	l = *(vuip)ioaddr;
> +	h = *(vuip)(ioaddr + (4 << 7));
> +	return h << 32 | l;
> +}
> +
>  __EXTERN_INLINE void jensen_outw(u16 b, unsigned long addr)
>  {
>  	jensen_set_hae(0);
> @@ -196,6 +207,16 @@ __EXTERN_INLINE void jensen_outl(u32 b, unsigned long addr)
>  	mb();
>  }
>  
> +__EXTERN_INLINE void jensen_outq(u64 b, unsigned long addr)
> +{
> +	unsigned long ioaddr = (addr << 7) + EISA_IO + 0x60;
> +
> +	jensen_set_hae(0);
> +	*(vuip)ioaddr = b;
> +	*(vuip)(ioaddr + (4 << 7)) = b >> 32;
> +	mb();
> +}
> +
>  /*
>   * Memory functions.
>   */
> @@ -303,8 +324,8 @@ __EXTERN_INLINE int jensen_is_mmio(const volatile void __iomem *addr)
>  /* New-style ioread interface.  All the routines are so ugly for Jensen
>     that it doesn't make sense to merge them.  */
>  
> -#define IOPORT(OS, NS)							\
> -__EXTERN_INLINE unsigned int jensen_ioread##NS(void __iomem *xaddr)	\
> +#define IOPORT(OS, NS, RT)						\
> +__EXTERN_INLINE RT jensen_ioread##NS(void __iomem *xaddr)		\
>  {									\
>  	if (jensen_is_mmio(xaddr))					\
>  		return jensen_read##OS(xaddr - 0x100000000ul);		\
> @@ -319,9 +340,10 @@ __EXTERN_INLINE void jensen_iowrite##NS(u##NS b, void __iomem *xaddr)	\
>  		jensen_out##OS(b, (unsigned long)xaddr);		\
>  }
>  
> -IOPORT(b, 8)
> -IOPORT(w, 16)
> -IOPORT(l, 32)
> +IOPORT(b, 8, unsigned int)
> +IOPORT(w, 16, unsigned int)
> +IOPORT(l, 32, unsigned int)
> +IOPORT(q, 64, u64)
>  
>  #undef IOPORT
>  
> diff --git a/arch/alpha/include/asm/machvec.h b/arch/alpha/include/asm/machvec.h
> index 75cb364..c037c7b 100644
> --- a/arch/alpha/include/asm/machvec.h
> +++ b/arch/alpha/include/asm/machvec.h
> @@ -48,10 +48,12 @@ struct alpha_machine_vector
>  	unsigned int (*mv_ioread8)(void __iomem *);
>  	unsigned int (*mv_ioread16)(void __iomem *);
>  	unsigned int (*mv_ioread32)(void __iomem *);
> +	u64 (*mv_ioread64)(void __iomem *);
>  
>  	void (*mv_iowrite8)(u8, void __iomem *);
>  	void (*mv_iowrite16)(u16, void __iomem *);
>  	void (*mv_iowrite32)(u32, void __iomem *);
> +	void (*mv_iowrite64)(u64, void __iomem *);
>  
>  	u8 (*mv_readb)(const volatile void __iomem *);
>  	u16 (*mv_readw)(const volatile void __iomem *);
> diff --git a/arch/alpha/kernel/io.c b/arch/alpha/kernel/io.c
> index 19c5875..d36146f 100644
> --- a/arch/alpha/kernel/io.c
> +++ b/arch/alpha/kernel/io.c
> @@ -34,6 +34,13 @@ unsigned int ioread32(void __iomem *addr)
>  	return ret;
>  }
>  
> +u64 ioread64(void __iomem *addr)
> +{
> +	u64 ret = IO_CONCAT(__IO_PREFIX,ioread64)(addr);
> +	mb();
> +	return ret;
> +}
> +
>  void iowrite8(u8 b, void __iomem *addr)
>  {
>  	IO_CONCAT(__IO_PREFIX,iowrite8)(b, addr);
> @@ -52,12 +59,20 @@ void iowrite32(u32 b, void __iomem *addr)
>  	mb();
>  }
>  
> +void iowrite64(u64 b, void __iomem *addr)
> +{
> +	IO_CONCAT(__IO_PREFIX,iowrite64)(b, addr);
> +	mb();
> +}
> +
>  EXPORT_SYMBOL(ioread8);
>  EXPORT_SYMBOL(ioread16);
>  EXPORT_SYMBOL(ioread32);
> +EXPORT_SYMBOL(ioread64);
>  EXPORT_SYMBOL(iowrite8);
>  EXPORT_SYMBOL(iowrite16);
>  EXPORT_SYMBOL(iowrite32);
> +EXPORT_SYMBOL(iowrite64);
>  
>  u8 inb(unsigned long port)
>  {
> @@ -74,6 +89,11 @@ u32 inl(unsigned long port)
>  	return ioread32(ioport_map(port, 4));
>  }
>  
> +u64 inq(unsigned long port)
> +{
> +	return ioread64(ioport_map(port, 8));
> +}
> +
>  void outb(u8 b, unsigned long port)
>  {
>  	iowrite8(b, ioport_map(port, 1));
> @@ -89,12 +109,19 @@ void outl(u32 b, unsigned long port)
>  	iowrite32(b, ioport_map(port, 4));
>  }
>  
> +void outq(u64 b, unsigned long port)
> +{
> +	iowrite64(b, ioport_map(port, 8));
> +}
> +
>  EXPORT_SYMBOL(inb);
>  EXPORT_SYMBOL(inw);
>  EXPORT_SYMBOL(inl);
> +EXPORT_SYMBOL(inq);
>  EXPORT_SYMBOL(outb);
>  EXPORT_SYMBOL(outw);
>  EXPORT_SYMBOL(outl);
> +EXPORT_SYMBOL(outq);
>  
>  u8 __raw_readb(const volatile void __iomem *addr)
>  {
> diff --git a/arch/alpha/kernel/machvec_impl.h b/arch/alpha/kernel/machvec_impl.h
> index b7d6960..9b37e19 100644
> --- a/arch/alpha/kernel/machvec_impl.h
> +++ b/arch/alpha/kernel/machvec_impl.h
> @@ -79,9 +79,11 @@
>  	.mv_ioread8 =		CAT(low,_ioread8),			\
>  	.mv_ioread16 =		CAT(low,_ioread16),			\
>  	.mv_ioread32 =		CAT(low,_ioread32),			\
> +	.mv_ioread64 =		CAT(low,_ioread64),			\
>  	.mv_iowrite8 =		CAT(low,_iowrite8),			\
>  	.mv_iowrite16 =		CAT(low,_iowrite16),			\
>  	.mv_iowrite32 =		CAT(low,_iowrite32),			\
> +	.mv_iowrite64 =		CAT(low,_iowrite64),			\
>  	.mv_readb =		CAT(low,_readb),			\
>  	.mv_readw =		CAT(low,_readw),			\
>  	.mv_readl =		CAT(low,_readl),			\
> 

[toc] | [prev] | [next] | [standalone]


#1674099

FromRichard Henderson <rth@twiddle.net>
Date2017-06-24 17:30 +0200
Message-ID<tVVax-141-19@gated-at.bofh.it>
In reply to#1674098
On 06/24/2017 08:19 AM, Logan Gunthorpe wrote:
> Hey,
> 
> On 24/06/17 09:13 AM, Richard Henderson wrote:
>> All Alpha hosts except for Jensen provide 64-bit I/O operations.
>>
>> Jensen is EISA only, so there ought not be any devices that even
>> attempt such operations.  But just in case, use 2 32-bit operations.
> 
> Thanks for this, Richard.
> 
> However, I was recently enlightened by the existence of the
> linux/io-64-nonatomic* headers. This is where the 2 32-bit operation
> functions belong. So you should probably remove them from this patch and
> let drivers that need them just include those headers.

This has nothing to do with drivers.

This is all about providing 64-bit operations for the 99.999% of alphas that do 
have them.


r~

[toc] | [prev] | [next] | [standalone]


#1674100

FromLogan Gunthorpe <logang@deltatee.com>
Date2017-06-24 17:40 +0200
Message-ID<tVVkd-179-5@gated-at.bofh.it>
In reply to#1674099

On 24/06/17 09:25 AM, Richard Henderson wrote:
> On 06/24/2017 08:19 AM, Logan Gunthorpe wrote:
>> Hey,
>>
>> On 24/06/17 09:13 AM, Richard Henderson wrote:
>>> All Alpha hosts except for Jensen provide 64-bit I/O operations.
>>>
>>> Jensen is EISA only, so there ought not be any devices that even
>>> attempt such operations.  But just in case, use 2 32-bit operations.
>>
>> Thanks for this, Richard.
>>
>> However, I was recently enlightened by the existence of the
>> linux/io-64-nonatomic* headers. This is where the 2 32-bit operation
>> functions belong. So you should probably remove them from this patch and
>> let drivers that need them just include those headers.
> 
> This has nothing to do with drivers.
> 
> This is all about providing 64-bit operations for the 99.999% of alphas
> that do have them.

As per the discussion with Arnd and Alan, that's not what they want.
Arches that have native 64bit operations should supply them. For drivers
that want to use them in the presence of arches that don't supply them,
they simply include one of the linux/io-64-nonatomic helper headers.

So, IMO, the Jensen inq and outq funtions in your patch, which I did
read, should probably just not be provided.

Logan

[toc] | [prev] | [next] | [standalone]


#1674104

FromRichard Henderson <rth@twiddle.net>
Date2017-06-24 18:20 +0200
Message-ID<tVVWW-1yN-5@gated-at.bofh.it>
In reply to#1674100
On 06/24/2017 08:32 AM, Logan Gunthorpe wrote:
> So, IMO, the Jensen inq and outq funtions in your patch, which I did
> read, should probably just not be provided.

So you would prefer a function containing BUG?
Because I have to have *something* to put into the machvec function pointer.


r~

[toc] | [prev] | [next] | [standalone]


#1674111

FromLogan Gunthorpe <logang@deltatee.com>
Date2017-06-24 19:20 +0200
Message-ID<tVWSZ-29D-3@gated-at.bofh.it>
In reply to#1674104

On 24/06/17 10:14 AM, Richard Henderson wrote:
> So you would prefer a function containing BUG?

Don't be so obtuse. Of course not.

> Because I have to have *something* to put into the machvec function
> pointer.

Well I can't say I understand the point of the machvec code, but if
you're saying it's impossible to have the Jensen sub-arch not supply a
64bit io functions then, fine, leave it as is.

Logan

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web