1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
2f15cbe6fSPaul Mundt #ifndef __ASM_SH_IO_H
3f15cbe6fSPaul Mundt #define __ASM_SH_IO_H
437b7a978SPaul Mundt
5f15cbe6fSPaul Mundt /*
6f15cbe6fSPaul Mundt * Convention:
714866543SPaul Mundt * read{b,w,l,q}/write{b,w,l,q} are for PCI,
8f15cbe6fSPaul Mundt * while in{b,w,l}/out{b,w,l} are for ISA
914866543SPaul Mundt *
10f15cbe6fSPaul Mundt * In addition we have 'pausing' versions: in{b,w,l}_p/out{b,w,l}_p
11f15cbe6fSPaul Mundt * and 'string' versions: ins{b,w,l}/outs{b,w,l}
12f15cbe6fSPaul Mundt *
1314866543SPaul Mundt * While read{b,w,l,q} and write{b,w,l,q} contain memory barriers
1414866543SPaul Mundt * automatically, there are also __raw versions, which do not.
15f15cbe6fSPaul Mundt */
164f744affSPaul Mundt #include <linux/errno.h>
17f15cbe6fSPaul Mundt #include <asm/cache.h>
18f15cbe6fSPaul Mundt #include <asm/addrspace.h>
19f15cbe6fSPaul Mundt #include <asm/machvec.h>
200cd39f46SPeter Zijlstra #include <asm/page.h>
21ca5999fdSMike Rapoport #include <linux/pgtable.h>
22f15cbe6fSPaul Mundt #include <asm-generic/iomap.h>
23f15cbe6fSPaul Mundt
24f15cbe6fSPaul Mundt #define __IO_PREFIX generic
25f15cbe6fSPaul Mundt #include <asm/io_generic.h>
26915c9e1bSMark Brown #include <asm-generic/pci_iomap.h>
27b7e68d68SPaul Mundt #include <mach/mangle-port.h>
28f15cbe6fSPaul Mundt
2914866543SPaul Mundt #define __raw_writeb(v,a) (__chk_io_ptr(a), *(volatile u8 __force *)(a) = (v))
3014866543SPaul Mundt #define __raw_writew(v,a) (__chk_io_ptr(a), *(volatile u16 __force *)(a) = (v))
3114866543SPaul Mundt #define __raw_writel(v,a) (__chk_io_ptr(a), *(volatile u32 __force *)(a) = (v))
3214866543SPaul Mundt #define __raw_writeq(v,a) (__chk_io_ptr(a), *(volatile u64 __force *)(a) = (v))
33f15cbe6fSPaul Mundt
3414866543SPaul Mundt #define __raw_readb(a) (__chk_io_ptr(a), *(volatile u8 __force *)(a))
3514866543SPaul Mundt #define __raw_readw(a) (__chk_io_ptr(a), *(volatile u16 __force *)(a))
3614866543SPaul Mundt #define __raw_readl(a) (__chk_io_ptr(a), *(volatile u32 __force *)(a))
3714866543SPaul Mundt #define __raw_readq(a) (__chk_io_ptr(a), *(volatile u64 __force *)(a))
38f15cbe6fSPaul Mundt
39b7e68d68SPaul Mundt #define readb_relaxed(c) ({ u8 __v = ioswabb(__raw_readb(c)); __v; })
40b7e68d68SPaul Mundt #define readw_relaxed(c) ({ u16 __v = ioswabw(__raw_readw(c)); __v; })
41b7e68d68SPaul Mundt #define readl_relaxed(c) ({ u32 __v = ioswabl(__raw_readl(c)); __v; })
42b7e68d68SPaul Mundt #define readq_relaxed(c) ({ u64 __v = ioswabq(__raw_readq(c)); __v; })
43f15cbe6fSPaul Mundt
44b7e68d68SPaul Mundt #define writeb_relaxed(v,c) ((void)__raw_writeb((__force u8)ioswabb(v),c))
45b7e68d68SPaul Mundt #define writew_relaxed(v,c) ((void)__raw_writew((__force u16)ioswabw(v),c))
46b7e68d68SPaul Mundt #define writel_relaxed(v,c) ((void)__raw_writel((__force u32)ioswabl(v),c))
47b7e68d68SPaul Mundt #define writeq_relaxed(v,c) ((void)__raw_writeq((__force u64)ioswabq(v),c))
4837b7a978SPaul Mundt
4937b7a978SPaul Mundt #define readb(a) ({ u8 r_ = readb_relaxed(a); rmb(); r_; })
5037b7a978SPaul Mundt #define readw(a) ({ u16 r_ = readw_relaxed(a); rmb(); r_; })
5137b7a978SPaul Mundt #define readl(a) ({ u32 r_ = readl_relaxed(a); rmb(); r_; })
5237b7a978SPaul Mundt #define readq(a) ({ u64 r_ = readq_relaxed(a); rmb(); r_; })
5337b7a978SPaul Mundt
5437b7a978SPaul Mundt #define writeb(v,a) ({ wmb(); writeb_relaxed((v),(a)); })
5537b7a978SPaul Mundt #define writew(v,a) ({ wmb(); writew_relaxed((v),(a)); })
5637b7a978SPaul Mundt #define writel(v,a) ({ wmb(); writel_relaxed((v),(a)); })
5737b7a978SPaul Mundt #define writeq(v,a) ({ wmb(); writeq_relaxed((v),(a)); })
5837b7a978SPaul Mundt
5937b7a978SPaul Mundt #define readsb(p,d,l) __raw_readsb(p,d,l)
6037b7a978SPaul Mundt #define readsw(p,d,l) __raw_readsw(p,d,l)
6137b7a978SPaul Mundt #define readsl(p,d,l) __raw_readsl(p,d,l)
6237b7a978SPaul Mundt
6337b7a978SPaul Mundt #define writesb(p,d,l) __raw_writesb(p,d,l)
6437b7a978SPaul Mundt #define writesw(p,d,l) __raw_writesw(p,d,l)
6537b7a978SPaul Mundt #define writesl(p,d,l) __raw_writesl(p,d,l)
6637b7a978SPaul Mundt
6737b7a978SPaul Mundt #define __BUILD_UNCACHED_IO(bwlq, type) \
6837b7a978SPaul Mundt static inline type read##bwlq##_uncached(unsigned long addr) \
6937b7a978SPaul Mundt { \
7037b7a978SPaul Mundt type ret; \
7137b7a978SPaul Mundt jump_to_uncached(); \
7237b7a978SPaul Mundt ret = __raw_read##bwlq(addr); \
7337b7a978SPaul Mundt back_to_cached(); \
7437b7a978SPaul Mundt return ret; \
7537b7a978SPaul Mundt } \
7637b7a978SPaul Mundt \
7737b7a978SPaul Mundt static inline void write##bwlq##_uncached(type v, unsigned long addr) \
7837b7a978SPaul Mundt { \
7937b7a978SPaul Mundt jump_to_uncached(); \
8037b7a978SPaul Mundt __raw_write##bwlq(v, addr); \
8137b7a978SPaul Mundt back_to_cached(); \
8237b7a978SPaul Mundt }
8337b7a978SPaul Mundt
8437b7a978SPaul Mundt __BUILD_UNCACHED_IO(b, u8)
8537b7a978SPaul Mundt __BUILD_UNCACHED_IO(w, u16)
8637b7a978SPaul Mundt __BUILD_UNCACHED_IO(l, u32)
8737b7a978SPaul Mundt __BUILD_UNCACHED_IO(q, u64)
8837b7a978SPaul Mundt
8937b7a978SPaul Mundt #define __BUILD_MEMORY_STRING(pfx, bwlq, type) \
9037b7a978SPaul Mundt \
9137b7a978SPaul Mundt static inline void \
9237b7a978SPaul Mundt pfx##writes##bwlq(volatile void __iomem *mem, const void *addr, \
9337b7a978SPaul Mundt unsigned int count) \
9437b7a978SPaul Mundt { \
9537b7a978SPaul Mundt const volatile type *__addr = addr; \
9637b7a978SPaul Mundt \
9737b7a978SPaul Mundt while (count--) { \
9837b7a978SPaul Mundt __raw_write##bwlq(*__addr, mem); \
9937b7a978SPaul Mundt __addr++; \
10037b7a978SPaul Mundt } \
10137b7a978SPaul Mundt } \
10237b7a978SPaul Mundt \
10337b7a978SPaul Mundt static inline void pfx##reads##bwlq(volatile void __iomem *mem, \
10437b7a978SPaul Mundt void *addr, unsigned int count) \
10537b7a978SPaul Mundt { \
10637b7a978SPaul Mundt volatile type *__addr = addr; \
10737b7a978SPaul Mundt \
10837b7a978SPaul Mundt while (count--) { \
10937b7a978SPaul Mundt *__addr = __raw_read##bwlq(mem); \
11037b7a978SPaul Mundt __addr++; \
11137b7a978SPaul Mundt } \
11237b7a978SPaul Mundt }
11337b7a978SPaul Mundt
11437b7a978SPaul Mundt __BUILD_MEMORY_STRING(__raw_, b, u8)
11537b7a978SPaul Mundt __BUILD_MEMORY_STRING(__raw_, w, u16)
11637b7a978SPaul Mundt
11737b7a978SPaul Mundt void __raw_writesl(void __iomem *addr, const void *data, int longlen);
11837b7a978SPaul Mundt void __raw_readsl(const void __iomem *addr, void *data, int longlen);
11937b7a978SPaul Mundt
12037b7a978SPaul Mundt __BUILD_MEMORY_STRING(__raw_, q, u64)
12137b7a978SPaul Mundt
122b94692e8SBaoquan He #define ioport_map ioport_map
123b94692e8SBaoquan He #define ioport_unmap ioport_unmap
124b94692e8SBaoquan He #define pci_iounmap pci_iounmap
125b94692e8SBaoquan He
126b94692e8SBaoquan He #define ioread8 ioread8
127b94692e8SBaoquan He #define ioread16 ioread16
128b94692e8SBaoquan He #define ioread16be ioread16be
129b94692e8SBaoquan He #define ioread32 ioread32
130b94692e8SBaoquan He #define ioread32be ioread32be
131b94692e8SBaoquan He
132b94692e8SBaoquan He #define iowrite8 iowrite8
133b94692e8SBaoquan He #define iowrite16 iowrite16
134b94692e8SBaoquan He #define iowrite16be iowrite16be
135b94692e8SBaoquan He #define iowrite32 iowrite32
136b94692e8SBaoquan He #define iowrite32be iowrite32be
137b94692e8SBaoquan He
138b94692e8SBaoquan He #define ioread8_rep ioread8_rep
139b94692e8SBaoquan He #define ioread16_rep ioread16_rep
140b94692e8SBaoquan He #define ioread32_rep ioread32_rep
141b94692e8SBaoquan He
142b94692e8SBaoquan He #define iowrite8_rep iowrite8_rep
143b94692e8SBaoquan He #define iowrite16_rep iowrite16_rep
144b94692e8SBaoquan He #define iowrite32_rep iowrite32_rep
145b94692e8SBaoquan He
146ce816fa8SUwe Kleine-König #ifdef CONFIG_HAS_IOPORT_MAP
14737b7a978SPaul Mundt
14837b7a978SPaul Mundt /*
14937b7a978SPaul Mundt * Slowdown I/O port space accesses for antique hardware.
15037b7a978SPaul Mundt */
15137b7a978SPaul Mundt #undef CONF_SLOWDOWN_IO
15237b7a978SPaul Mundt
15337b7a978SPaul Mundt /*
15437b7a978SPaul Mundt * On SuperH I/O ports are memory mapped, so we access them using normal
15537b7a978SPaul Mundt * load/store instructions. sh_io_port_base is the virtual address to
15637b7a978SPaul Mundt * which all ports are being mapped.
15737b7a978SPaul Mundt */
158666e81fdSAndi Kleen extern unsigned long sh_io_port_base;
15937b7a978SPaul Mundt
__set_io_port_base(unsigned long pbase)16037b7a978SPaul Mundt static inline void __set_io_port_base(unsigned long pbase)
16137b7a978SPaul Mundt {
16237b7a978SPaul Mundt *(unsigned long *)&sh_io_port_base = pbase;
16337b7a978SPaul Mundt barrier();
16437b7a978SPaul Mundt }
16537b7a978SPaul Mundt
16637b7a978SPaul Mundt #ifdef CONFIG_GENERIC_IOMAP
16737b7a978SPaul Mundt #define __ioport_map ioport_map
16837b7a978SPaul Mundt #else
16937b7a978SPaul Mundt extern void __iomem *__ioport_map(unsigned long addr, unsigned int size);
17037b7a978SPaul Mundt #endif
17137b7a978SPaul Mundt
17237b7a978SPaul Mundt #ifdef CONF_SLOWDOWN_IO
17337b7a978SPaul Mundt #define SLOW_DOWN_IO __raw_readw(sh_io_port_base)
17437b7a978SPaul Mundt #else
17537b7a978SPaul Mundt #define SLOW_DOWN_IO
17637b7a978SPaul Mundt #endif
17737b7a978SPaul Mundt
17837b7a978SPaul Mundt #define __BUILD_IOPORT_SINGLE(pfx, bwlq, type, p, slow) \
17937b7a978SPaul Mundt \
18037b7a978SPaul Mundt static inline void pfx##out##bwlq##p(type val, unsigned long port) \
18137b7a978SPaul Mundt { \
18237b7a978SPaul Mundt volatile type *__addr; \
18337b7a978SPaul Mundt \
18437b7a978SPaul Mundt __addr = __ioport_map(port, sizeof(type)); \
18537b7a978SPaul Mundt *__addr = val; \
18637b7a978SPaul Mundt slow; \
18737b7a978SPaul Mundt } \
18837b7a978SPaul Mundt \
18937b7a978SPaul Mundt static inline type pfx##in##bwlq##p(unsigned long port) \
19037b7a978SPaul Mundt { \
19137b7a978SPaul Mundt volatile type *__addr; \
19237b7a978SPaul Mundt type __val; \
19337b7a978SPaul Mundt \
19437b7a978SPaul Mundt __addr = __ioport_map(port, sizeof(type)); \
19537b7a978SPaul Mundt __val = *__addr; \
19637b7a978SPaul Mundt slow; \
19737b7a978SPaul Mundt \
19837b7a978SPaul Mundt return __val; \
19937b7a978SPaul Mundt }
20037b7a978SPaul Mundt
20137b7a978SPaul Mundt #define __BUILD_IOPORT_PFX(bus, bwlq, type) \
20237b7a978SPaul Mundt __BUILD_IOPORT_SINGLE(bus, bwlq, type, ,) \
20337b7a978SPaul Mundt __BUILD_IOPORT_SINGLE(bus, bwlq, type, _p, SLOW_DOWN_IO)
20437b7a978SPaul Mundt
20537b7a978SPaul Mundt #define BUILDIO_IOPORT(bwlq, type) \
20637b7a978SPaul Mundt __BUILD_IOPORT_PFX(, bwlq, type)
20737b7a978SPaul Mundt
20837b7a978SPaul Mundt BUILDIO_IOPORT(b, u8)
20937b7a978SPaul Mundt BUILDIO_IOPORT(w, u16)
21037b7a978SPaul Mundt BUILDIO_IOPORT(l, u32)
21137b7a978SPaul Mundt BUILDIO_IOPORT(q, u64)
21237b7a978SPaul Mundt
21337b7a978SPaul Mundt #define __BUILD_IOPORT_STRING(bwlq, type) \
21437b7a978SPaul Mundt \
21537b7a978SPaul Mundt static inline void outs##bwlq(unsigned long port, const void *addr, \
21637b7a978SPaul Mundt unsigned int count) \
21737b7a978SPaul Mundt { \
21837b7a978SPaul Mundt const volatile type *__addr = addr; \
21937b7a978SPaul Mundt \
22037b7a978SPaul Mundt while (count--) { \
22137b7a978SPaul Mundt out##bwlq(*__addr, port); \
22237b7a978SPaul Mundt __addr++; \
22337b7a978SPaul Mundt } \
22437b7a978SPaul Mundt } \
22537b7a978SPaul Mundt \
22637b7a978SPaul Mundt static inline void ins##bwlq(unsigned long port, void *addr, \
22737b7a978SPaul Mundt unsigned int count) \
22837b7a978SPaul Mundt { \
22937b7a978SPaul Mundt volatile type *__addr = addr; \
23037b7a978SPaul Mundt \
23137b7a978SPaul Mundt while (count--) { \
23237b7a978SPaul Mundt *__addr = in##bwlq(port); \
23337b7a978SPaul Mundt __addr++; \
23437b7a978SPaul Mundt } \
23537b7a978SPaul Mundt }
23637b7a978SPaul Mundt
23737b7a978SPaul Mundt __BUILD_IOPORT_STRING(b, u8)
23837b7a978SPaul Mundt __BUILD_IOPORT_STRING(w, u16)
23937b7a978SPaul Mundt __BUILD_IOPORT_STRING(l, u32)
24037b7a978SPaul Mundt __BUILD_IOPORT_STRING(q, u64)
24137b7a978SPaul Mundt
242ce816fa8SUwe Kleine-König #else /* !CONFIG_HAS_IOPORT_MAP */
243c5e50fa9SPaul Mundt
244c5e50fa9SPaul Mundt #include <asm/io_noioport.h>
245c5e50fa9SPaul Mundt
24637b7a978SPaul Mundt #endif
247f15cbe6fSPaul Mundt
248b94692e8SBaoquan He #define inb(addr) inb(addr)
249b94692e8SBaoquan He #define inw(addr) inw(addr)
250b94692e8SBaoquan He #define inl(addr) inl(addr)
251b94692e8SBaoquan He #define outb(x, addr) outb((x), (addr))
252b94692e8SBaoquan He #define outw(x, addr) outw((x), (addr))
253b94692e8SBaoquan He #define outl(x, addr) outl((x), (addr))
254b94692e8SBaoquan He
255b94692e8SBaoquan He #define inb_p(addr) inb(addr)
256b94692e8SBaoquan He #define inw_p(addr) inw(addr)
257b94692e8SBaoquan He #define inl_p(addr) inl(addr)
258b94692e8SBaoquan He #define outb_p(x, addr) outb((x), (addr))
259b94692e8SBaoquan He #define outw_p(x, addr) outw((x), (addr))
260b94692e8SBaoquan He #define outl_p(x, addr) outl((x), (addr))
261b94692e8SBaoquan He
262b94692e8SBaoquan He #define insb insb
263b94692e8SBaoquan He #define insw insw
264b94692e8SBaoquan He #define insl insl
265b94692e8SBaoquan He #define outsb outsb
266b94692e8SBaoquan He #define outsw outsw
267b94692e8SBaoquan He #define outsl outsl
268c5e50fa9SPaul Mundt
26937b7a978SPaul Mundt #define IO_SPACE_LIMIT 0xffffffff
270f15cbe6fSPaul Mundt
271f15cbe6fSPaul Mundt /* We really want to try and get these to memcpy etc */
272b94692e8SBaoquan He #define memset_io memset_io
273b94692e8SBaoquan He #define memcpy_fromio memcpy_fromio
274b94692e8SBaoquan He #define memcpy_toio memcpy_toio
27514866543SPaul Mundt void memcpy_fromio(void *, const volatile void __iomem *, unsigned long);
27614866543SPaul Mundt void memcpy_toio(volatile void __iomem *, const void *, unsigned long);
27714866543SPaul Mundt void memset_io(volatile void __iomem *, int, unsigned long);
278f15cbe6fSPaul Mundt
279f15cbe6fSPaul Mundt /* Quad-word real-mode I/O, don't ask.. */
280f15cbe6fSPaul Mundt unsigned long long peek_real_address_q(unsigned long long addr);
281f15cbe6fSPaul Mundt unsigned long long poke_real_address_q(unsigned long long addr,
282f15cbe6fSPaul Mundt unsigned long long val);
283f15cbe6fSPaul Mundt
284f15cbe6fSPaul Mundt #if !defined(CONFIG_MMU)
285f15cbe6fSPaul Mundt #define virt_to_phys(address) ((unsigned long)(address))
286f15cbe6fSPaul Mundt #define phys_to_virt(address) ((void *)(address))
287f15cbe6fSPaul Mundt #else
288f15cbe6fSPaul Mundt #define virt_to_phys(address) (__pa(address))
289f15cbe6fSPaul Mundt #define phys_to_virt(address) (__va(address))
290f15cbe6fSPaul Mundt #endif
291f15cbe6fSPaul Mundt
292f15cbe6fSPaul Mundt #ifdef CONFIG_MMU
293*0453c9a7SBaoquan He /*
294*0453c9a7SBaoquan He * I/O memory mapping functions.
295*0453c9a7SBaoquan He */
296*0453c9a7SBaoquan He #define ioremap_prot ioremap_prot
297*0453c9a7SBaoquan He #define iounmap iounmap
298f15cbe6fSPaul Mundt
299*0453c9a7SBaoquan He #define _PAGE_IOREMAP pgprot_val(PAGE_KERNEL_NOCACHE)
300d57d6408SPaul Mundt
301*0453c9a7SBaoquan He #define ioremap_cache(addr, size) \
302*0453c9a7SBaoquan He ioremap_prot((addr), (size), pgprot_val(PAGE_KERNEL))
30313f1fc87SChristoph Hellwig #endif /* CONFIG_MMU */
304d627a2ebSPaul Mundt
3054c73e892SLuis R. Rodriguez #define ioremap_uc ioremap
306733f0025SSam Ravnborg
307f15cbe6fSPaul Mundt /*
308f15cbe6fSPaul Mundt * Convert a physical pointer to a virtual kernel pointer for /dev/mem
309f15cbe6fSPaul Mundt * access
310f15cbe6fSPaul Mundt */
311f15cbe6fSPaul Mundt #define xlate_dev_mem_ptr(p) __va(p)
3127497840dSGuenter Roeck #define unxlate_dev_mem_ptr(p, v) do { } while (0)
313f15cbe6fSPaul Mundt
314b94692e8SBaoquan He #include <asm-generic/io.h>
315b94692e8SBaoquan He
316185aed75SPaul Mundt #define ARCH_HAS_VALID_PHYS_ADDR_RANGE
3177e6735c3SCyril Chemparathy int valid_phys_addr_range(phys_addr_t addr, size_t size);
318185aed75SPaul Mundt int valid_mmap_phys_addr_range(unsigned long pfn, size_t size);
319185aed75SPaul Mundt
320f15cbe6fSPaul Mundt #endif /* __ASM_SH_IO_H */
321