Commit e19d4ebc authored by Arnd Bergmann's avatar Arnd Bergmann

alpha: add full ioread64/iowrite64 implementation

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: default avatarGuenter Roeck <linux@roeck-us.net>
Tested-by: default avatarGuenter Roeck <linux@roeck-us.net>
Reviewed-by: default avatarLinus Walleij <linus.walleij@linaro.org>
Fixes: 7e772dad ("alpha: Use generic <asm-generic/io.h>")
Signed-off-by: default avatarArnd Bergmann <arnd@arndb.de>
parent 28a679ea
......@@ -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);
......
......@@ -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);
......
......@@ -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);
......
......@@ -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);
}
......
......@@ -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
......
......@@ -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
......
......@@ -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)
......
......@@ -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
......
......@@ -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
......
......@@ -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 *);
......
......@@ -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;
......
......@@ -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)
{
......
......@@ -78,9 +78,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), \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment