xref: /openbmc/linux/include/linux/io.h (revision 2612e3bbc0386368a850140a6c9b990cd496a5ec)
1775c8a3dSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-only */
2c27a0d75SBryan O'Sullivan /*
3c27a0d75SBryan O'Sullivan  * Copyright 2006 PathScale, Inc.  All Rights Reserved.
4c27a0d75SBryan O'Sullivan  */
5c27a0d75SBryan O'Sullivan 
6c27a0d75SBryan O'Sullivan #ifndef _LINUX_IO_H
7c27a0d75SBryan O'Sullivan #define _LINUX_IO_H
8c27a0d75SBryan O'Sullivan 
9cb1055fbSAl Viro #include <linux/types.h>
10d6472302SStephen Rothwell #include <linux/init.h>
1141e94a85SChristoph Hellwig #include <linux/bug.h>
1241e94a85SChristoph Hellwig #include <linux/err.h>
13c27a0d75SBryan O'Sullivan #include <asm/io.h>
1474588d8bSHaavard Skinnemoen #include <asm/page.h>
15c27a0d75SBryan O'Sullivan 
167f253770SAndrew Morton struct device;
1741e94a85SChristoph Hellwig struct resource;
187f253770SAndrew Morton 
19d47d5c81SAndi Kleen __visible void __iowrite32_copy(void __iomem *to, const void *from, size_t count);
20a9aec588SStephen Boyd void __ioread32_copy(void *to, const void __iomem *from, size_t count);
2122ae813bSBrice Goglin void __iowrite64_copy(void __iomem *to, const void *from, size_t count);
22c27a0d75SBryan O'Sullivan 
23218f0aaeSPaul Mundt #ifdef CONFIG_MMU
2474588d8bSHaavard Skinnemoen int ioremap_page_range(unsigned long addr, unsigned long end,
25ffa71f33SKenji Kaneshige 		       phys_addr_t phys_addr, pgprot_t prot);
26218f0aaeSPaul Mundt #else
ioremap_page_range(unsigned long addr,unsigned long end,phys_addr_t phys_addr,pgprot_t prot)27218f0aaeSPaul Mundt static inline int ioremap_page_range(unsigned long addr, unsigned long end,
28ffa71f33SKenji Kaneshige 				     phys_addr_t phys_addr, pgprot_t prot)
29218f0aaeSPaul Mundt {
30218f0aaeSPaul Mundt 	return 0;
31218f0aaeSPaul Mundt }
32218f0aaeSPaul Mundt #endif
3374588d8bSHaavard Skinnemoen 
349ac7849eSTejun Heo /*
359ac7849eSTejun Heo  * Managed iomap interface
369ac7849eSTejun Heo  */
37ce816fa8SUwe Kleine-König #ifdef CONFIG_HAS_IOPORT_MAP
389ac7849eSTejun Heo void __iomem * devm_ioport_map(struct device *dev, unsigned long port,
399ac7849eSTejun Heo 			       unsigned int nr);
409ac7849eSTejun Heo void devm_ioport_unmap(struct device *dev, void __iomem *addr);
4193da2879SRussell King #else
devm_ioport_map(struct device * dev,unsigned long port,unsigned int nr)4293da2879SRussell King static inline void __iomem *devm_ioport_map(struct device *dev,
4393da2879SRussell King 					     unsigned long port,
4493da2879SRussell King 					     unsigned int nr)
4593da2879SRussell King {
4693da2879SRussell King 	return NULL;
4793da2879SRussell King }
4893da2879SRussell King 
devm_ioport_unmap(struct device * dev,void __iomem * addr)4993da2879SRussell King static inline void devm_ioport_unmap(struct device *dev, void __iomem *addr)
5093da2879SRussell King {
5193da2879SRussell King }
5293da2879SRussell King #endif
539ac7849eSTejun Heo 
54efd342fbSMatthias Brugger #define IOMEM_ERR_PTR(err) (__force void __iomem *)ERR_PTR(err)
55efd342fbSMatthias Brugger 
564f452e8aSKumar Gala void __iomem *devm_ioremap(struct device *dev, resource_size_t offset,
575559b7bcSCristian Stoica 			   resource_size_t size);
58e537654bSTuowen Zhao void __iomem *devm_ioremap_uc(struct device *dev, resource_size_t offset,
59e537654bSTuowen Zhao 				   resource_size_t size);
6034644524SAbhilash Kesavan void __iomem *devm_ioremap_wc(struct device *dev, resource_size_t offset,
6134644524SAbhilash Kesavan 				   resource_size_t size);
629ac7849eSTejun Heo void devm_iounmap(struct device *dev, void __iomem *addr);
63cc2ea416SAndrew Morton int check_signature(const volatile void __iomem *io_addr,
64cc2ea416SAndrew Morton 			const unsigned char *signature, int length);
65b41e5fffSEmil Medve void devm_ioremap_release(struct device *dev, void *res);
66e50190a8SMatthew Wilcox 
677d3dcf26SChristoph Hellwig void *devm_memremap(struct device *dev, resource_size_t offset,
687d3dcf26SChristoph Hellwig 		size_t size, unsigned long flags);
697d3dcf26SChristoph Hellwig void devm_memunmap(struct device *dev, void *addr);
707d3dcf26SChristoph Hellwig 
71*4d312ac0SArnd Bergmann /* architectures can override this */
72*4d312ac0SArnd Bergmann pgprot_t __init early_memremap_pgprot_adjust(resource_size_t phys_addr,
73*4d312ac0SArnd Bergmann 					unsigned long size, pgprot_t prot);
74*4d312ac0SArnd Bergmann 
75*4d312ac0SArnd Bergmann 
76cf9ea8caSLorenzo Pieralisi #ifdef CONFIG_PCI
77cf9ea8caSLorenzo Pieralisi /*
78cf9ea8caSLorenzo Pieralisi  * The PCI specifications (Rev 3.0, 3.2.5 "Transaction Ordering and
79b10eb2d5SHector Martin  * Posting") mandate non-posted configuration transactions. This default
80b10eb2d5SHector Martin  * implementation attempts to use the ioremap_np() API to provide this
81b10eb2d5SHector Martin  * on arches that support it, and falls back to ioremap() on those that
82b10eb2d5SHector Martin  * don't. Overriding this function is deprecated; arches that properly
83b10eb2d5SHector Martin  * support non-posted accesses should implement ioremap_np() instead, which
84b10eb2d5SHector Martin  * this default implementation can then use to return mappings compliant with
85b10eb2d5SHector Martin  * the PCI specification.
86cf9ea8caSLorenzo Pieralisi  */
87cf9ea8caSLorenzo Pieralisi #ifndef pci_remap_cfgspace
88cf9ea8caSLorenzo Pieralisi #define pci_remap_cfgspace pci_remap_cfgspace
pci_remap_cfgspace(phys_addr_t offset,size_t size)89cf9ea8caSLorenzo Pieralisi static inline void __iomem *pci_remap_cfgspace(phys_addr_t offset,
90cf9ea8caSLorenzo Pieralisi 					       size_t size)
91cf9ea8caSLorenzo Pieralisi {
92b10eb2d5SHector Martin 	return ioremap_np(offset, size) ?: ioremap(offset, size);
93cf9ea8caSLorenzo Pieralisi }
94cf9ea8caSLorenzo Pieralisi #endif
95cf9ea8caSLorenzo Pieralisi #endif
96cf9ea8caSLorenzo Pieralisi 
97e1612de9SHaren Myneni /*
98e1612de9SHaren Myneni  * Some systems do not have legacy ISA devices.
99e1612de9SHaren Myneni  * /dev/port is not a valid interface on these systems.
100e1612de9SHaren Myneni  * So for those archs, <asm/io.h> should define the following symbol.
101e1612de9SHaren Myneni  */
102e1612de9SHaren Myneni #ifndef arch_has_dev_port
103e1612de9SHaren Myneni #define arch_has_dev_port()     (1)
104e1612de9SHaren Myneni #endif
105e1612de9SHaren Myneni 
106d0d98eedSAndy Lutomirski /*
107d0d98eedSAndy Lutomirski  * Some systems (x86 without PAT) have a somewhat reliable way to mark a
108d0d98eedSAndy Lutomirski  * physical address range such that uncached mappings will actually
109d0d98eedSAndy Lutomirski  * end up write-combining.  This facility should be used in conjunction
110d0d98eedSAndy Lutomirski  * with pgprot_writecombine, ioremap-wc, or set_memory_wc, since it has
111d0d98eedSAndy Lutomirski  * no effect if the per-page mechanisms are functional.
112d0d98eedSAndy Lutomirski  * (On x86 without PAT, these functions manipulate MTRRs.)
113d0d98eedSAndy Lutomirski  *
114d0d98eedSAndy Lutomirski  * arch_phys_del_wc(0) or arch_phys_del_wc(any error code) is guaranteed
115d0d98eedSAndy Lutomirski  * to have no effect.
116d0d98eedSAndy Lutomirski  */
117d0d98eedSAndy Lutomirski #ifndef arch_phys_wc_add
arch_phys_wc_add(unsigned long base,unsigned long size)118d0d98eedSAndy Lutomirski static inline int __must_check arch_phys_wc_add(unsigned long base,
119d0d98eedSAndy Lutomirski 						unsigned long size)
120d0d98eedSAndy Lutomirski {
121d0d98eedSAndy Lutomirski 	return 0;  /* It worked (i.e. did nothing). */
122d0d98eedSAndy Lutomirski }
123d0d98eedSAndy Lutomirski 
arch_phys_wc_del(int handle)124d0d98eedSAndy Lutomirski static inline void arch_phys_wc_del(int handle)
125d0d98eedSAndy Lutomirski {
126d0d98eedSAndy Lutomirski }
127d0d98eedSAndy Lutomirski 
128d0d98eedSAndy Lutomirski #define arch_phys_wc_add arch_phys_wc_add
1297d010fdfSLuis R. Rodriguez #ifndef arch_phys_wc_index
arch_phys_wc_index(int handle)1307d010fdfSLuis R. Rodriguez static inline int arch_phys_wc_index(int handle)
1317d010fdfSLuis R. Rodriguez {
1327d010fdfSLuis R. Rodriguez 	return -1;
1337d010fdfSLuis R. Rodriguez }
1347d010fdfSLuis R. Rodriguez #define arch_phys_wc_index arch_phys_wc_index
1357d010fdfSLuis R. Rodriguez #endif
136d0d98eedSAndy Lutomirski #endif
137d0d98eedSAndy Lutomirski 
1383229b906SThomas Zimmermann int devm_arch_phys_wc_add(struct device *dev, unsigned long base, unsigned long size);
1393229b906SThomas Zimmermann 
14092281deeSDan Williams enum {
14192281deeSDan Williams 	/* See memremap() kernel-doc for usage description... */
14292281deeSDan Williams 	MEMREMAP_WB = 1 << 0,
14392281deeSDan Williams 	MEMREMAP_WT = 1 << 1,
144c907e0ebSBrian Starkey 	MEMREMAP_WC = 1 << 2,
1458f716c9bSTom Lendacky 	MEMREMAP_ENC = 1 << 3,
1468f716c9bSTom Lendacky 	MEMREMAP_DEC = 1 << 4,
14792281deeSDan Williams };
14892281deeSDan Williams 
14992281deeSDan Williams void *memremap(resource_size_t offset, size_t size, unsigned long flags);
15092281deeSDan Williams void memunmap(void *addr);
15192281deeSDan Williams 
1528ef42276SDave Airlie /*
1538ef42276SDave Airlie  * On x86 PAT systems we have memory tracking that keeps track of
1548ef42276SDave Airlie  * the allowed mappings on memory ranges. This tracking works for
1558ef42276SDave Airlie  * all the in-kernel mapping APIs (ioremap*), but where the user
1568ef42276SDave Airlie  * wishes to map a range from a physical device into user memory
1578ef42276SDave Airlie  * the tracking won't be updated. This API is to be used by
1588ef42276SDave Airlie  * drivers which remap physical device pages into userspace,
1598ef42276SDave Airlie  * and wants to make sure they are mapped WC and not UC.
1608ef42276SDave Airlie  */
1618ef42276SDave Airlie #ifndef arch_io_reserve_memtype_wc
arch_io_reserve_memtype_wc(resource_size_t base,resource_size_t size)1628ef42276SDave Airlie static inline int arch_io_reserve_memtype_wc(resource_size_t base,
1638ef42276SDave Airlie 					     resource_size_t size)
1648ef42276SDave Airlie {
1658ef42276SDave Airlie 	return 0;
1668ef42276SDave Airlie }
1678ef42276SDave Airlie 
arch_io_free_memtype_wc(resource_size_t base,resource_size_t size)1688ef42276SDave Airlie static inline void arch_io_free_memtype_wc(resource_size_t base,
1698ef42276SDave Airlie 					   resource_size_t size)
1708ef42276SDave Airlie {
1718ef42276SDave Airlie }
1728ef42276SDave Airlie #endif
1738ef42276SDave Airlie 
174c8223107SThomas Zimmermann int devm_arch_io_reserve_memtype_wc(struct device *dev, resource_size_t start,
175c8223107SThomas Zimmermann 				    resource_size_t size);
176c8223107SThomas Zimmermann 
177c27a0d75SBryan O'Sullivan #endif /* _LINUX_IO_H */
178