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

[POWERPC] Add function to check if address is an IO port

This adds a function that tells you if a given kernel virtual address
is hitting a PCI or ISA IO port permanent mapping or not. This is to
be used in the next patch to fix iomap APIs to properly unmap things.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Paul Mackerras <paulus@samba.org>

authored by

Benjamin Herrenschmidt and committed by
Paul Mackerras
6dfbde20 f5d834fc

+43
+23
arch/powerpc/kernel/pci-common.c
··· 101 101 kfree(phb); 102 102 } 103 103 104 + int pcibios_vaddr_is_ioport(void __iomem *address) 105 + { 106 + int ret = 0; 107 + struct pci_controller *hose; 108 + unsigned long size; 109 + 110 + spin_lock(&hose_spinlock); 111 + list_for_each_entry(hose, &hose_list, list_node) { 112 + #ifdef CONFIG_PPC64 113 + size = hose->pci_io_size; 114 + #else 115 + size = hose->io_resource.end - hose->io_resource.start + 1; 116 + #endif 117 + if (address >= hose->io_base_virt && 118 + address < (hose->io_base_virt + size)) { 119 + ret = 1; 120 + break; 121 + } 122 + } 123 + spin_unlock(&hose_spinlock); 124 + return ret; 125 + } 126 + 104 127 /* 105 128 * Return the domain number for this bus. 106 129 */
+20
include/asm-powerpc/pci-bridge.h
··· 71 71 return bus->sysdata; 72 72 } 73 73 74 + static inline int isa_vaddr_is_ioport(void __iomem *address) 75 + { 76 + /* No specific ISA handling on ppc32 at this stage, it 77 + * all goes through PCI 78 + */ 79 + return 0; 80 + } 81 + 74 82 /* These are used for config access before all the PCI probing 75 83 has been done. */ 76 84 int early_read_config_byte(struct pci_controller *hose, int bus, int dev_fn, ··· 249 241 250 242 extern void isa_bridge_find_early(struct pci_controller *hose); 251 243 244 + static inline int isa_vaddr_is_ioport(void __iomem *address) 245 + { 246 + /* Check if address hits the reserved legacy IO range */ 247 + unsigned long ea = (unsigned long)address; 248 + return ea >= ISA_IO_BASE && ea < ISA_IO_END; 249 + } 250 + 252 251 extern int pcibios_unmap_io_space(struct pci_bus *bus); 253 252 extern int pcibios_map_io_space(struct pci_bus *bus); 254 253 ··· 286 271 pcibios_alloc_controller(struct device_node *dev); 287 272 #ifdef CONFIG_PCI 288 273 extern unsigned long pci_address_to_pio(phys_addr_t address); 274 + extern int pcibios_vaddr_is_ioport(void __iomem *address); 289 275 #else 290 276 static inline unsigned long pci_address_to_pio(phys_addr_t address) 291 277 { 292 278 return (unsigned long)-1; 279 + } 280 + static inline int pcibios_vaddr_is_ioport(void __iomem *address) 281 + { 282 + return 0; 293 283 } 294 284 #endif 295 285