1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Re-map IO memory to kernel address space so that we can access it. 4 * This is needed for high PCI addresses that aren't mapped in the 5 * 640k-1MB IO memory area on PC's 6 * 7 * (C) Copyright 1995 1996 Linus Torvalds 8 */ 9 #include <linux/vmalloc.h> 10 #include <linux/mm.h> 11 #include <linux/io.h> 12 #include <linux/export.h> 13 14 void __iomem *generic_ioremap_prot(phys_addr_t phys_addr, size_t size, 15 pgprot_t prot) 16 { 17 unsigned long offset, vaddr; 18 phys_addr_t last_addr; 19 struct vm_struct *area; 20 21 /* An early platform driver might end up here */ 22 if (WARN_ON_ONCE(!slab_is_available())) 23 return NULL; 24 25 /* Disallow wrap-around or zero size */ 26 last_addr = phys_addr + size - 1; 27 if (!size || last_addr < phys_addr) 28 return NULL; 29 30 /* Page-align mappings */ 31 offset = phys_addr & (~PAGE_MASK); 32 phys_addr -= offset; 33 size = PAGE_ALIGN(size + offset); 34 35 if (!ioremap_allowed(phys_addr, size, pgprot_val(prot))) 36 return NULL; 37 38 area = get_vm_area_caller(size, VM_IOREMAP, 39 __builtin_return_address(0)); 40 if (!area) 41 return NULL; 42 vaddr = (unsigned long)area->addr; 43 area->phys_addr = phys_addr; 44 45 if (ioremap_page_range(vaddr, vaddr + size, phys_addr, prot)) { 46 free_vm_area(area); 47 return NULL; 48 } 49 50 return (void __iomem *)(vaddr + offset); 51 } 52 53 #ifndef ioremap_prot 54 void __iomem *ioremap_prot(phys_addr_t phys_addr, size_t size, 55 unsigned long prot) 56 { 57 return generic_ioremap_prot(phys_addr, size, __pgprot(prot)); 58 } 59 EXPORT_SYMBOL(ioremap_prot); 60 #endif 61 62 void generic_iounmap(volatile void __iomem *addr) 63 { 64 void *vaddr = (void *)((unsigned long)addr & PAGE_MASK); 65 66 if (!iounmap_allowed(vaddr)) 67 return; 68 69 if (is_vmalloc_addr(vaddr)) 70 vunmap(vaddr); 71 } 72 73 #ifndef iounmap 74 void iounmap(volatile void __iomem *addr) 75 { 76 generic_iounmap(addr); 77 } 78 EXPORT_SYMBOL(iounmap); 79 #endif 80