18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * I/O remap functions for Hexagon 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. 68c2ecf20Sopenharmony_ci */ 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci#include <linux/io.h> 98c2ecf20Sopenharmony_ci#include <linux/vmalloc.h> 108c2ecf20Sopenharmony_ci#include <linux/mm.h> 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_civoid __iomem *ioremap(unsigned long phys_addr, unsigned long size) 138c2ecf20Sopenharmony_ci{ 148c2ecf20Sopenharmony_ci unsigned long last_addr, addr; 158c2ecf20Sopenharmony_ci unsigned long offset = phys_addr & ~PAGE_MASK; 168c2ecf20Sopenharmony_ci struct vm_struct *area; 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_ci pgprot_t prot = __pgprot(_PAGE_PRESENT|_PAGE_READ|_PAGE_WRITE 198c2ecf20Sopenharmony_ci |(__HEXAGON_C_DEV << 6)); 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_ci last_addr = phys_addr + size - 1; 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_ci /* Wrapping not allowed */ 248c2ecf20Sopenharmony_ci if (!size || (last_addr < phys_addr)) 258c2ecf20Sopenharmony_ci return NULL; 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_ci /* Rounds up to next page size, including whole-page offset */ 288c2ecf20Sopenharmony_ci size = PAGE_ALIGN(offset + size); 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_ci area = get_vm_area(size, VM_IOREMAP); 318c2ecf20Sopenharmony_ci addr = (unsigned long)area->addr; 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_ci if (ioremap_page_range(addr, addr+size, phys_addr, prot)) { 348c2ecf20Sopenharmony_ci vunmap((void *)addr); 358c2ecf20Sopenharmony_ci return NULL; 368c2ecf20Sopenharmony_ci } 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_ci return (void __iomem *) (offset + addr); 398c2ecf20Sopenharmony_ci} 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_civoid iounmap(const volatile void __iomem *addr) 428c2ecf20Sopenharmony_ci{ 438c2ecf20Sopenharmony_ci vunmap((void *) ((unsigned long) addr & PAGE_MASK)); 448c2ecf20Sopenharmony_ci} 45