1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Implement the default iomap interfaces 4 * 5 * (C) Copyright 2004 Linus Torvalds 6 */ 7 #include <linux/pci.h> 8 #include <linux/io.h> 9 10 #include <linux/export.h> 11 12 /** 13 * pci_iomap_range - create a virtual mapping cookie for a PCI BAR 14 * @dev: PCI device that owns the BAR 15 * @bar: BAR number 16 * @offset: map memory at the given offset in BAR 17 * @maxlen: max length of the memory to map 18 * 19 * Using this function you will get a __iomem address to your device BAR. 20 * You can access it using ioread*() and iowrite*(). These functions hide 21 * the details if this is a MMIO or PIO address space and will just do what 22 * you expect from them in the correct way. 23 * 24 * @maxlen specifies the maximum length to map. If you want to get access to 25 * the complete BAR from offset to the end, pass %0 here. 26 * */ 27 void __iomem *pci_iomap_range(struct pci_dev *dev, 28 int bar, 29 unsigned long offset, 30 unsigned long maxlen) 31 { 32 resource_size_t start = pci_resource_start(dev, bar); 33 resource_size_t len = pci_resource_len(dev, bar); 34 unsigned long flags = pci_resource_flags(dev, bar); 35 36 if (len <= offset || !start) 37 return NULL; 38 len -= offset; 39 start += offset; 40 if (maxlen && len > maxlen) 41 len = maxlen; 42 if (flags & IORESOURCE_IO) 43 return __pci_ioport_map(dev, start, len); 44 if (flags & IORESOURCE_MEM) 45 return ioremap(start, len); 46 /* What? */ 47 return NULL; 48 } 49 EXPORT_SYMBOL(pci_iomap_range); 50 51 /** 52 * pci_iomap_wc_range - create a virtual WC mapping cookie for a PCI BAR 53 * @dev: PCI device that owns the BAR 54 * @bar: BAR number 55 * @offset: map memory at the given offset in BAR 56 * @maxlen: max length of the memory to map 57 * 58 * Using this function you will get a __iomem address to your device BAR. 59 * You can access it using ioread*() and iowrite*(). These functions hide 60 * the details if this is a MMIO or PIO address space and will just do what 61 * you expect from them in the correct way. When possible write combining 62 * is used. 63 * 64 * @maxlen specifies the maximum length to map. If you want to get access to 65 * the complete BAR from offset to the end, pass %0 here. 66 * */ 67 void __iomem *pci_iomap_wc_range(struct pci_dev *dev, 68 int bar, 69 unsigned long offset, 70 unsigned long maxlen) 71 { 72 resource_size_t start = pci_resource_start(dev, bar); 73 resource_size_t len = pci_resource_len(dev, bar); 74 unsigned long flags = pci_resource_flags(dev, bar); 75 76 77 if (flags & IORESOURCE_IO) 78 return NULL; 79 80 if (len <= offset || !start) 81 return NULL; 82 83 len -= offset; 84 start += offset; 85 if (maxlen && len > maxlen) 86 len = maxlen; 87 88 if (flags & IORESOURCE_MEM) 89 return ioremap_wc(start, len); 90 91 /* What? */ 92 return NULL; 93 } 94 EXPORT_SYMBOL_GPL(pci_iomap_wc_range); 95 96 /** 97 * pci_iomap - create a virtual mapping cookie for a PCI BAR 98 * @dev: PCI device that owns the BAR 99 * @bar: BAR number 100 * @maxlen: length of the memory to map 101 * 102 * Using this function you will get a __iomem address to your device BAR. 103 * You can access it using ioread*() and iowrite*(). These functions hide 104 * the details if this is a MMIO or PIO address space and will just do what 105 * you expect from them in the correct way. 106 * 107 * @maxlen specifies the maximum length to map. If you want to get access to 108 * the complete BAR without checking for its length first, pass %0 here. 109 * */ 110 void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen) 111 { 112 return pci_iomap_range(dev, bar, 0, maxlen); 113 } 114 EXPORT_SYMBOL(pci_iomap); 115 116 /** 117 * pci_iomap_wc - create a virtual WC mapping cookie for a PCI BAR 118 * @dev: PCI device that owns the BAR 119 * @bar: BAR number 120 * @maxlen: length of the memory to map 121 * 122 * Using this function you will get a __iomem address to your device BAR. 123 * You can access it using ioread*() and iowrite*(). These functions hide 124 * the details if this is a MMIO or PIO address space and will just do what 125 * you expect from them in the correct way. When possible write combining 126 * is used. 127 * 128 * @maxlen specifies the maximum length to map. If you want to get access to 129 * the complete BAR without checking for its length first, pass %0 here. 130 * */ 131 void __iomem *pci_iomap_wc(struct pci_dev *dev, int bar, unsigned long maxlen) 132 { 133 return pci_iomap_wc_range(dev, bar, 0, maxlen); 134 } 135 EXPORT_SYMBOL_GPL(pci_iomap_wc); 136 137 /* 138 * pci_iounmap() somewhat illogically comes from lib/iomap.c for the 139 * CONFIG_GENERIC_IOMAP case, because that's the code that knows about 140 * the different IOMAP ranges. 141 * 142 * But if the architecture does not use the generic iomap code, and if 143 * it has _not_ defined it's own private pci_iounmap function, we define 144 * it here. 145 * 146 * NOTE! This default implementation assumes that if the architecture 147 * support ioport mapping (HAS_IOPORT_MAP), the ioport mapping will 148 * be fixed to the range [ PCI_IOBASE, PCI_IOBASE+IO_SPACE_LIMIT [, 149 * and does not need unmapping with 'ioport_unmap()'. 150 * 151 * If you have different rules for your architecture, you need to 152 * implement your own pci_iounmap() that knows the rules for where 153 * and how IO vs MEM get mapped. 154 * 155 * This code is odd, and the ARCH_HAS/ARCH_WANTS #define logic comes 156 * from legacy <asm-generic/io.h> header file behavior. In particular, 157 * it would seem to make sense to do the iounmap(p) for the non-IO-space 158 * case here regardless, but that's not what the old header file code 159 * did. Probably incorrectly, but this is meant to be bug-for-bug 160 * compatible. 161 */ 162 #if defined(ARCH_WANTS_GENERIC_PCI_IOUNMAP) 163 164 void pci_iounmap(struct pci_dev *dev, void __iomem *p) 165 { 166 #ifdef ARCH_HAS_GENERIC_IOPORT_MAP 167 uintptr_t start = (uintptr_t) PCI_IOBASE; 168 uintptr_t addr = (uintptr_t) p; 169 170 if (addr >= start && addr < start + IO_SPACE_LIMIT) 171 return; 172 #endif 173 iounmap(p); 174 } 175 EXPORT_SYMBOL(pci_iounmap); 176 177 #endif /* ARCH_WANTS_GENERIC_PCI_IOUNMAP */ 178