1013de2d6SGuo Ren // SPDX-License-Identifier: GPL-2.0 2013de2d6SGuo Ren // Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. 3013de2d6SGuo Ren 4013de2d6SGuo Ren #include <linux/export.h> 5013de2d6SGuo Ren #include <linux/mm.h> 6013de2d6SGuo Ren #include <linux/vmalloc.h> 7013de2d6SGuo Ren #include <linux/io.h> 8013de2d6SGuo Ren 9013de2d6SGuo Ren #include <asm/pgtable.h> 10013de2d6SGuo Ren 11013de2d6SGuo Ren void __iomem *ioremap(phys_addr_t addr, size_t size) 12013de2d6SGuo Ren { 13013de2d6SGuo Ren phys_addr_t last_addr; 14013de2d6SGuo Ren unsigned long offset, vaddr; 15013de2d6SGuo Ren struct vm_struct *area; 16013de2d6SGuo Ren pgprot_t prot; 17013de2d6SGuo Ren 18013de2d6SGuo Ren last_addr = addr + size - 1; 19013de2d6SGuo Ren if (!size || last_addr < addr) 20013de2d6SGuo Ren return NULL; 21013de2d6SGuo Ren 22013de2d6SGuo Ren offset = addr & (~PAGE_MASK); 23013de2d6SGuo Ren addr &= PAGE_MASK; 24013de2d6SGuo Ren size = PAGE_ALIGN(size + offset); 25013de2d6SGuo Ren 26013de2d6SGuo Ren area = get_vm_area_caller(size, VM_ALLOC, __builtin_return_address(0)); 27013de2d6SGuo Ren if (!area) 28013de2d6SGuo Ren return NULL; 29013de2d6SGuo Ren 30013de2d6SGuo Ren vaddr = (unsigned long)area->addr; 31013de2d6SGuo Ren 32*7f80fe20SGuo Ren prot = pgprot_noncached(PAGE_KERNEL); 33013de2d6SGuo Ren 34013de2d6SGuo Ren if (ioremap_page_range(vaddr, vaddr + size, addr, prot)) { 35013de2d6SGuo Ren free_vm_area(area); 36013de2d6SGuo Ren return NULL; 37013de2d6SGuo Ren } 38013de2d6SGuo Ren 39013de2d6SGuo Ren return (void __iomem *)(vaddr + offset); 40013de2d6SGuo Ren } 41013de2d6SGuo Ren EXPORT_SYMBOL(ioremap); 42013de2d6SGuo Ren 43013de2d6SGuo Ren void iounmap(void __iomem *addr) 44013de2d6SGuo Ren { 45013de2d6SGuo Ren vunmap((void *)((unsigned long)addr & PAGE_MASK)); 46013de2d6SGuo Ren } 47013de2d6SGuo Ren EXPORT_SYMBOL(iounmap); 4876d21d18SGuo Ren 4976d21d18SGuo Ren pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, 5076d21d18SGuo Ren unsigned long size, pgprot_t vma_prot) 5176d21d18SGuo Ren { 5276d21d18SGuo Ren if (!pfn_valid(pfn)) { 5376d21d18SGuo Ren return pgprot_noncached(vma_prot); 5476d21d18SGuo Ren } else if (file->f_flags & O_SYNC) { 55*7f80fe20SGuo Ren return pgprot_writecombine(vma_prot); 5676d21d18SGuo Ren } 5776d21d18SGuo Ren 5876d21d18SGuo Ren return vma_prot; 5976d21d18SGuo Ren } 6076d21d18SGuo Ren EXPORT_SYMBOL(phys_mem_access_prot); 61