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 *ioremap_prot(phys_addr_t addr, size_t size, unsigned long prot) 15 { 16 unsigned long offset, vaddr; 17 phys_addr_t last_addr; 18 struct vm_struct *area; 19 20 /* Disallow wrap-around or zero size */ 21 last_addr = addr + size - 1; 22 if (!size || last_addr < addr) 23 return NULL; 24 25 /* Page-align mappings */ 26 offset = addr & (~PAGE_MASK); 27 addr -= offset; 28 size = PAGE_ALIGN(size + offset); 29 30 area = get_vm_area_caller(size, VM_IOREMAP, 31 __builtin_return_address(0)); 32 if (!area) 33 return NULL; 34 vaddr = (unsigned long)area->addr; 35 36 if (ioremap_page_range(vaddr, vaddr + size, addr, __pgprot(prot))) { 37 free_vm_area(area); 38 return NULL; 39 } 40 41 return (void __iomem *)(vaddr + offset); 42 } 43 EXPORT_SYMBOL(ioremap_prot); 44 45 void iounmap(volatile void __iomem *addr) 46 { 47 vunmap((void *)((unsigned long)addr & PAGE_MASK)); 48 } 49 EXPORT_SYMBOL(iounmap); 50