Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

io-64-nonatomic: Add relaxed accessor variants

Whilst commit 9439eb3ab9d1 ("asm-generic: io: implement relaxed
accessor macros as conditional wrappers") makes the *_relaxed forms of
I/O accessors universally available to drivers, in cases where writeq()
is implemented via the io-64-nonatomic helpers, writeq_relaxed() will
end up falling back to writel() regardless of whether writel_relaxed()
is available (identically for s/write/read/).

Add corresponding relaxed forms of the nonatomic helpers to delegate
to the equivalent 32-bit accessors as appropriate. We also need to fix
io.h to avoid defining default relaxed variants if the basic accessors
themselves don't exist.

CC: Christoph Hellwig <hch@lst.de>
CC: Darren Hart <dvhart@linux.intel.com>
CC: Hitoshi Mitake <mitake.hitoshi@lab.ntt.co.jp>
Acked-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Robin Murphy <robin.murphy@arm.com>
Signed-off-by: Will Deacon <will.deacon@arm.com>

authored by

Robin Murphy and committed by
Will Deacon
e511267b f0cfffc4

+52 -2
+2 -2
include/asm-generic/io.h
··· 191 191 #define readl_relaxed readl 192 192 #endif 193 193 194 - #ifndef readq_relaxed 194 + #if defined(readq) && !defined(readq_relaxed) 195 195 #define readq_relaxed readq 196 196 #endif 197 197 ··· 207 207 #define writel_relaxed writel 208 208 #endif 209 209 210 - #ifndef writeq_relaxed 210 + #if defined(writeq) && !defined(writeq_relaxed) 211 211 #define writeq_relaxed writeq 212 212 #endif 213 213
+25
include/linux/io-64-nonatomic-hi-lo.h
··· 21 21 writel(val, addr); 22 22 } 23 23 24 + static inline __u64 hi_lo_readq_relaxed(const volatile void __iomem *addr) 25 + { 26 + const volatile u32 __iomem *p = addr; 27 + u32 low, high; 28 + 29 + high = readl_relaxed(p + 1); 30 + low = readl_relaxed(p); 31 + 32 + return low + ((u64)high << 32); 33 + } 34 + 35 + static inline void hi_lo_writeq_relaxed(__u64 val, volatile void __iomem *addr) 36 + { 37 + writel_relaxed(val >> 32, addr + 4); 38 + writel_relaxed(val, addr); 39 + } 40 + 24 41 #ifndef readq 25 42 #define readq hi_lo_readq 26 43 #endif 27 44 28 45 #ifndef writeq 29 46 #define writeq hi_lo_writeq 47 + #endif 48 + 49 + #ifndef readq_relaxed 50 + #define readq_relaxed hi_lo_readq_relaxed 51 + #endif 52 + 53 + #ifndef writeq_relaxed 54 + #define writeq_relaxed hi_lo_writeq_relaxed 30 55 #endif 31 56 32 57 #endif /* _LINUX_IO_64_NONATOMIC_HI_LO_H_ */
+25
include/linux/io-64-nonatomic-lo-hi.h
··· 21 21 writel(val >> 32, addr + 4); 22 22 } 23 23 24 + static inline __u64 lo_hi_readq_relaxed(const volatile void __iomem *addr) 25 + { 26 + const volatile u32 __iomem *p = addr; 27 + u32 low, high; 28 + 29 + low = readl_relaxed(p); 30 + high = readl_relaxed(p + 1); 31 + 32 + return low + ((u64)high << 32); 33 + } 34 + 35 + static inline void lo_hi_writeq_relaxed(__u64 val, volatile void __iomem *addr) 36 + { 37 + writel_relaxed(val, addr); 38 + writel_relaxed(val >> 32, addr + 4); 39 + } 40 + 24 41 #ifndef readq 25 42 #define readq lo_hi_readq 26 43 #endif 27 44 28 45 #ifndef writeq 29 46 #define writeq lo_hi_writeq 47 + #endif 48 + 49 + #ifndef readq_relaxed 50 + #define readq_relaxed lo_hi_readq_relaxed 51 + #endif 52 + 53 + #ifndef writeq_relaxed 54 + #define writeq_relaxed lo_hi_writeq_relaxed 30 55 #endif 31 56 32 57 #endif /* _LINUX_IO_64_NONATOMIC_LO_HI_H_ */