alpha: add full ioread64/iowrite64 implementation
authorArnd Bergmann <arnd@arndb.de>
Mon, 3 Oct 2022 11:12:54 +0000 (13:12 +0200)
committerArnd Bergmann <arnd@arndb.de>
Tue, 4 Oct 2022 09:23:29 +0000 (11:23 +0200)
The previous patch introduced ioread64/iowrite64 declarations, but
this means we no longer get the io-64-nonatomic variant, and
run into a long error when someone actually wants to use these:

ERROR: modpost: "ioread64" [drivers/net/ethernet/freescale/enetc/fsl-enetc.ko] undefined!

Add the (hopefully) correct implementation for each machine type,
based on the 32-bit accessor. Since the 32-bit return type does
not work for ioread64(), change the internal implementation to use
the correct width consistently, but leave the external interface
to match the asm-generic/iomap.h header that uses 32-bit or 64-bit
return values.

Reported-by: Guenter Roeck <linux@roeck-us.net>
Tested-by: Guenter Roeck <linux@roeck-us.net>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Fixes: 7e772dad9913 ("alpha: Use generic <asm-generic/io.h>")
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
13 files changed:
arch/alpha/include/asm/core_apecs.h
arch/alpha/include/asm/core_cia.h
arch/alpha/include/asm/core_lca.h
arch/alpha/include/asm/core_marvel.h
arch/alpha/include/asm/core_mcpcia.h
arch/alpha/include/asm/core_t2.h
arch/alpha/include/asm/io.h
arch/alpha/include/asm/io_trivial.h
arch/alpha/include/asm/jensen.h
arch/alpha/include/asm/machvec.h
arch/alpha/kernel/core_marvel.c
arch/alpha/kernel/io.c
arch/alpha/kernel/machvec_impl.h

index 2d9726f..69a2fc6 100644 (file)
@@ -384,7 +384,7 @@ struct el_apecs_procdata
                }                                               \
        } while (0)
 
-__EXTERN_INLINE unsigned int apecs_ioread8(const void __iomem *xaddr)
+__EXTERN_INLINE u8 apecs_ioread8(const void __iomem *xaddr)
 {
        unsigned long addr = (unsigned long) xaddr;
        unsigned long result, base_and_type;
@@ -420,7 +420,7 @@ __EXTERN_INLINE void apecs_iowrite8(u8 b, void __iomem *xaddr)
        *(vuip) ((addr << 5) + base_and_type) = w;
 }
 
-__EXTERN_INLINE unsigned int apecs_ioread16(const void __iomem *xaddr)
+__EXTERN_INLINE u16 apecs_ioread16(const void __iomem *xaddr)
 {
        unsigned long addr = (unsigned long) xaddr;
        unsigned long result, base_and_type;
@@ -456,7 +456,7 @@ __EXTERN_INLINE void apecs_iowrite16(u16 b, void __iomem *xaddr)
        *(vuip) ((addr << 5) + base_and_type) = w;
 }
 
-__EXTERN_INLINE unsigned int apecs_ioread32(const void __iomem *xaddr)
+__EXTERN_INLINE u32 apecs_ioread32(const void __iomem *xaddr)
 {
        unsigned long addr = (unsigned long) xaddr;
        if (addr < APECS_DENSE_MEM)
@@ -472,6 +472,22 @@ __EXTERN_INLINE void apecs_iowrite32(u32 b, void __iomem *xaddr)
        *(vuip)addr = b;
 }
 
+__EXTERN_INLINE u64 apecs_ioread64(const void __iomem *xaddr)
+{
+       unsigned long addr = (unsigned long) xaddr;
+       if (addr < APECS_DENSE_MEM)
+               addr = ((addr - APECS_IO) << 5) + APECS_IO + 0x18;
+       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 + 0x18;
+       *(vulp)addr = b;
+}
+
 __EXTERN_INLINE void __iomem *apecs_ioportmap(unsigned long addr)
 {
        return (void __iomem *)(addr + APECS_IO);
index cb22991..d26bdfb 100644 (file)
@@ -342,7 +342,7 @@ struct el_CIA_sysdata_mcheck {
 #define vuip   volatile unsigned int __force *
 #define vulp   volatile unsigned long __force *
 
-__EXTERN_INLINE unsigned int cia_ioread8(const void __iomem *xaddr)
+__EXTERN_INLINE u8 cia_ioread8(const void __iomem *xaddr)
 {
        unsigned long addr = (unsigned long) xaddr;
        unsigned long result, base_and_type;
@@ -374,7 +374,7 @@ __EXTERN_INLINE void cia_iowrite8(u8 b, void __iomem *xaddr)
        *(vuip) ((addr << 5) + base_and_type) = w;
 }
 
-__EXTERN_INLINE unsigned int cia_ioread16(const void __iomem *xaddr)
+__EXTERN_INLINE u16 cia_ioread16(const void __iomem *xaddr)
 {
        unsigned long addr = (unsigned long) xaddr;
        unsigned long result, base_and_type;
@@ -404,7 +404,7 @@ __EXTERN_INLINE void cia_iowrite16(u16 b, void __iomem *xaddr)
        *(vuip) ((addr << 5) + base_and_type) = w;
 }
 
-__EXTERN_INLINE unsigned int cia_ioread32(const void __iomem *xaddr)
+__EXTERN_INLINE u32 cia_ioread32(const void __iomem *xaddr)
 {
        unsigned long addr = (unsigned long) xaddr;
        if (addr < CIA_DENSE_MEM)
@@ -420,6 +420,22 @@ __EXTERN_INLINE void cia_iowrite32(u32 b, void __iomem *xaddr)
        *(vuip)addr = b;
 }
 
+__EXTERN_INLINE u64 cia_ioread64(const void __iomem *xaddr)
+{
+       unsigned long addr = (unsigned long) xaddr;
+       if (addr < CIA_DENSE_MEM)
+               addr = ((addr - CIA_IO) << 5) + CIA_IO + 0x18;
+       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 + 0x18;
+       *(vulp)addr = b;
+}
+
 __EXTERN_INLINE void __iomem *cia_ioportmap(unsigned long addr)
 {
        return (void __iomem *)(addr + CIA_IO);
index ec86314..d8c3e72 100644 (file)
@@ -230,7 +230,7 @@ union el_lca {
        } while (0)
 
 
-__EXTERN_INLINE unsigned int lca_ioread8(const void __iomem *xaddr)
+__EXTERN_INLINE u8 lca_ioread8(const void __iomem *xaddr)
 {
        unsigned long addr = (unsigned long) xaddr;
        unsigned long result, base_and_type;
@@ -266,7 +266,7 @@ __EXTERN_INLINE void lca_iowrite8(u8 b, void __iomem *xaddr)
        *(vuip) ((addr << 5) + base_and_type) = w;
 }
 
-__EXTERN_INLINE unsigned int lca_ioread16(const void __iomem *xaddr)
+__EXTERN_INLINE u16 lca_ioread16(const void __iomem *xaddr)
 {
        unsigned long addr = (unsigned long) xaddr;
        unsigned long result, base_and_type;
@@ -302,7 +302,7 @@ __EXTERN_INLINE void lca_iowrite16(u16 b, void __iomem *xaddr)
        *(vuip) ((addr << 5) + base_and_type) = w;
 }
 
-__EXTERN_INLINE unsigned int lca_ioread32(const void __iomem *xaddr)
+__EXTERN_INLINE u32 lca_ioread32(const void __iomem *xaddr)
 {
        unsigned long addr = (unsigned long) xaddr;
        if (addr < LCA_DENSE_MEM)
@@ -318,6 +318,22 @@ __EXTERN_INLINE void lca_iowrite32(u32 b, void __iomem *xaddr)
        *(vuip)addr = b;
 }
 
+__EXTERN_INLINE u64 lca_ioread64(const void __iomem *xaddr)
+{
+       unsigned long addr = (unsigned long) xaddr;
+       if (addr < LCA_DENSE_MEM)
+               addr = ((addr - LCA_IO) << 5) + LCA_IO + 0x18;
+       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 + 0x18;
+       *(vulp)addr = b;
+}
+
 __EXTERN_INLINE void __iomem *lca_ioportmap(unsigned long addr)
 {
        return (void __iomem *)(addr + LCA_IO);
index b266e02..d99f3a8 100644 (file)
@@ -332,10 +332,10 @@ struct io7 {
 #define vucp   volatile unsigned char __force *
 #define vusp   volatile unsigned short __force *
 
-extern unsigned int marvel_ioread8(const void __iomem *);
+extern u8 marvel_ioread8(const void __iomem *);
 extern void marvel_iowrite8(u8 b, void __iomem *);
 
-__EXTERN_INLINE unsigned int marvel_ioread16(const void __iomem *addr)
+__EXTERN_INLINE u16 marvel_ioread16(const void __iomem *addr)
 {
        return __kernel_ldwu(*(vusp)addr);
 }
index cb24d1b..ed2bf8a 100644 (file)
@@ -248,6 +248,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                                               \
@@ -267,7 +268,7 @@ extern inline int __mcpcia_is_mmio(unsigned long addr)
        return (addr & 0x80000000UL) == 0;
 }
 
-__EXTERN_INLINE unsigned int mcpcia_ioread8(const void __iomem *xaddr)
+__EXTERN_INLINE u8 mcpcia_ioread8(const void __iomem *xaddr)
 {
        unsigned long addr = (unsigned long)xaddr & MCPCIA_MEM_MASK;
        unsigned long hose = (unsigned long)xaddr & ~MCPCIA_MEM_MASK;
@@ -291,7 +292,7 @@ __EXTERN_INLINE void mcpcia_iowrite8(u8 b, void __iomem *xaddr)
        *(vuip) ((addr << 5) + hose + 0x00) = w;
 }
 
-__EXTERN_INLINE unsigned int mcpcia_ioread16(const void __iomem *xaddr)
+__EXTERN_INLINE u16 mcpcia_ioread16(const void __iomem *xaddr)
 {
        unsigned long addr = (unsigned long)xaddr & MCPCIA_MEM_MASK;
        unsigned long hose = (unsigned long)xaddr & ~MCPCIA_MEM_MASK;
@@ -315,7 +316,7 @@ __EXTERN_INLINE void mcpcia_iowrite16(u16 b, void __iomem *xaddr)
        *(vuip) ((addr << 5) + hose + 0x08) = w;
 }
 
-__EXTERN_INLINE unsigned int mcpcia_ioread32(const void __iomem *xaddr)
+__EXTERN_INLINE u32 mcpcia_ioread32(const void __iomem *xaddr)
 {
        unsigned long addr = (unsigned long)xaddr;
 
@@ -335,6 +336,26 @@ __EXTERN_INLINE void mcpcia_iowrite32(u32 b, void __iomem *xaddr)
        *(vuip)addr = b;
 }
 
+__EXTERN_INLINE u64 mcpcia_ioread64(const void __iomem *xaddr)
+{
+       unsigned long addr = (unsigned long)xaddr;
+
+       if (!__mcpcia_is_mmio(addr))
+               addr = ((addr & 0xffff) << 5) + (addr & ~0xfffful) + 0x18;
+
+       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) + 0x18;
+
+       *(vulp)addr = b;
+}
+
 
 __EXTERN_INLINE void __iomem *mcpcia_ioportmap(unsigned long addr)
 {
@@ -362,6 +383,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
index 12bb7ad..ab956b1 100644 (file)
@@ -360,6 +360,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)
 {
@@ -402,6 +403,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 + 0x18);
+}
+
+extern inline void t2_outq(u64 b, unsigned long addr)
+{
+       *(vulp) ((addr << 5) + T2_IO + 0x18) = b;
+       mb();
+}
+
 
 /*
  * Memory functions.
@@ -572,7 +584,7 @@ __EXTERN_INLINE int t2_is_mmio(const volatile void __iomem *addr)
    it doesn't make sense to merge the pio and mmio routines.  */
 
 #define IOPORT(OS, NS)                                                 \
-__EXTERN_INLINE unsigned int t2_ioread##NS(const void __iomem *xaddr)          \
+__EXTERN_INLINE u##NS t2_ioread##NS(const void __iomem *xaddr)         \
 {                                                                      \
        if (t2_is_mmio(xaddr))                                          \
                return t2_read##OS(xaddr);                              \
@@ -590,11 +602,13 @@ __EXTERN_INLINE void t2_iowrite##NS(u##NS b, void __iomem *xaddr) \
 IOPORT(b, 8)
 IOPORT(w, 16)
 IOPORT(l, 32)
+IOPORT(q, 64)
 
 #undef IOPORT
 
 #undef vip
 #undef vuip
+#undef vulp
 
 #undef __IO_PREFIX
 #define __IO_PREFIX            t2
index a887628..1c3605d 100644 (file)
@@ -155,6 +155,7 @@ static inline void generic_##NAME(TYPE b, QUAL void __iomem *addr)  \
 REMAP1(unsigned int, ioread8, const)
 REMAP1(unsigned int, ioread16, const)
 REMAP1(unsigned int, ioread32, const)
+REMAP1(u64, ioread64, const)
 REMAP1(u8, readb, const volatile)
 REMAP1(u16, readw, const volatile)
 REMAP1(u32, readl, const volatile)
@@ -163,6 +164,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)
@@ -400,12 +402,27 @@ extern inline unsigned int ioread32(const void __iomem *addr)
        return ret;
 }
 
+extern inline u64 ioread64(const void __iomem *addr)
+{
+       unsigned int ret;
+       mb();
+       ret = IO_CONCAT(__IO_PREFIX,ioread64)(addr);
+       mb();
+       return ret;
+}
+
 extern inline void iowrite32(u32 b, void __iomem *addr)
 {
        mb();
        IO_CONCAT(__IO_PREFIX, iowrite32)(b, addr);
 }
 
+extern inline void iowrite64(u64 b, void __iomem *addr)
+{
+       mb();
+       IO_CONCAT(__IO_PREFIX, iowrite64)(b, addr);
+}
+
 extern inline u32 inl(unsigned long port)
 {
        return ioread32(ioport_map(port, 4));
@@ -418,7 +435,9 @@ extern inline void outl(u32 b, unsigned long port)
 #endif
 
 #define ioread32 ioread32
+#define ioread64 ioread64
 #define iowrite32 iowrite32
+#define iowrite64 iowrite64
 
 #if IO_CONCAT(__IO_PREFIX,trivial_rw_bw) == 1
 extern inline u8 __raw_readb(const volatile void __iomem *addr)
index a1a29cb..0003209 100644 (file)
@@ -6,13 +6,13 @@
 /* This file may be included multiple times.  */
 
 #if IO_CONCAT(__IO_PREFIX,trivial_io_bw)
-__EXTERN_INLINE unsigned int
+__EXTERN_INLINE u8
 IO_CONCAT(__IO_PREFIX,ioread8)(const void __iomem *a)
 {
        return __kernel_ldbu(*(const volatile u8 __force *)a);
 }
 
-__EXTERN_INLINE unsigned int
+__EXTERN_INLINE u16
 IO_CONCAT(__IO_PREFIX,ioread16)(const void __iomem *a)
 {
        return __kernel_ldwu(*(const volatile u16 __force *)a);
@@ -32,7 +32,7 @@ IO_CONCAT(__IO_PREFIX,iowrite16)(u16 b, void __iomem *a)
 #endif
 
 #if IO_CONCAT(__IO_PREFIX,trivial_io_lq)
-__EXTERN_INLINE unsigned int
+__EXTERN_INLINE u32
 IO_CONCAT(__IO_PREFIX,ioread32)(const void __iomem *a)
 {
        return *(const volatile u32 __force *)a;
@@ -43,6 +43,18 @@ IO_CONCAT(__IO_PREFIX,iowrite32)(u32 b, void __iomem *a)
 {
        *(volatile u32 __force *)a = b;
 }
+
+__EXTERN_INLINE u64
+IO_CONCAT(__IO_PREFIX,ioread64)(const void __iomem *a)
+{
+       return *(const volatile u64 __force *)a;
+}
+
+__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
index 1c41314..66eb049 100644 (file)
@@ -98,6 +98,7 @@ __EXTERN_INLINE void jensen_set_hae(unsigned long addr)
 }
 
 #define vuip   volatile unsigned int *
+#define vulp   volatile unsigned long *
 
 /*
  * IO functions
@@ -183,6 +184,12 @@ __EXTERN_INLINE u32 jensen_inl(unsigned long addr)
        return *(vuip) ((addr << 7) + EISA_IO + 0x60);
 }
 
+__EXTERN_INLINE u64 jensen_inq(unsigned long addr)
+{
+       jensen_set_hae(0);
+       return *(vulp) ((addr << 7) + EISA_IO + 0x60);
+}
+
 __EXTERN_INLINE void jensen_outw(u16 b, unsigned long addr)
 {
        jensen_set_hae(0);
@@ -197,6 +204,13 @@ __EXTERN_INLINE void jensen_outl(u32 b, unsigned long addr)
        mb();
 }
 
+__EXTERN_INLINE void jensen_outq(u64 b, unsigned long addr)
+{
+       jensen_set_hae(0);
+       *(vulp) ((addr << 7) + EISA_IO + 0x60) = b;
+       mb();
+}
+
 /*
  * Memory functions.
  */
@@ -305,7 +319,7 @@ __EXTERN_INLINE int jensen_is_mmio(const volatile void __iomem *addr)
    that it doesn't make sense to merge them.  */
 
 #define IOPORT(OS, NS)                                                 \
-__EXTERN_INLINE unsigned int jensen_ioread##NS(const void __iomem *xaddr)      \
+__EXTERN_INLINE u##NS jensen_ioread##NS(const void __iomem *xaddr)     \
 {                                                                      \
        if (jensen_is_mmio(xaddr))                                      \
                return jensen_read##OS(xaddr - 0x100000000ul);          \
@@ -323,10 +337,12 @@ __EXTERN_INLINE void jensen_iowrite##NS(u##NS b, void __iomem *xaddr)     \
 IOPORT(b, 8)
 IOPORT(w, 16)
 IOPORT(l, 32)
+IOPORT(q, 64)
 
 #undef IOPORT
 
 #undef vuip
+#undef vulp
 
 #undef __IO_PREFIX
 #define __IO_PREFIX            jensen
index e49fabc..8623f99 100644 (file)
@@ -46,13 +46,15 @@ struct alpha_machine_vector
        void (*mv_pci_tbi)(struct pci_controller *hose,
                           dma_addr_t start, dma_addr_t end);
 
-       unsigned int (*mv_ioread8)(const void __iomem *);
-       unsigned int (*mv_ioread16)(const void __iomem *);
-       unsigned int (*mv_ioread32)(const void __iomem *);
+       u8 (*mv_ioread8)(const void __iomem *);
+       u16 (*mv_ioread16)(const void __iomem *);
+       u32 (*mv_ioread32)(const void __iomem *);
+       u64 (*mv_ioread64)(const 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 *);
index 1efca79..6d0b3ba 100644 (file)
@@ -803,7 +803,7 @@ void __iomem *marvel_ioportmap (unsigned long addr)
        return (void __iomem *)addr;
 }
 
-unsigned int
+unsigned u8
 marvel_ioread8(const void __iomem *xaddr)
 {
        unsigned long addr = (unsigned long) xaddr;
index 838586a..eda0977 100644 (file)
@@ -41,6 +41,15 @@ unsigned int ioread32(const void __iomem *addr)
        return ret;
 }
 
+u64 ioread64(const void __iomem *addr)
+{
+       unsigned int ret;
+       mb();
+       ret = IO_CONCAT(__IO_PREFIX,ioread64)(addr);
+       mb();
+       return ret;
+}
+
 void iowrite8(u8 b, void __iomem *addr)
 {
        mb();
@@ -59,12 +68,20 @@ void iowrite32(u32 b, void __iomem *addr)
        IO_CONCAT(__IO_PREFIX,iowrite32)(b, addr);
 }
 
+void iowrite64(u64 b, void __iomem *addr)
+{
+       mb();
+       IO_CONCAT(__IO_PREFIX,iowrite64)(b, addr);
+}
+
 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)
 {
index 393d5d6..c2ebcb3 100644 (file)
        .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),                        \