1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-only 2*4882a593Smuzhiyun /* 3*4882a593Smuzhiyun * I/O remap functions for Hexagon 4*4882a593Smuzhiyun * 5*4882a593Smuzhiyun * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. 6*4882a593Smuzhiyun */ 7*4882a593Smuzhiyun 8*4882a593Smuzhiyun #include <linux/io.h> 9*4882a593Smuzhiyun #include <linux/vmalloc.h> 10*4882a593Smuzhiyun #include <linux/mm.h> 11*4882a593Smuzhiyun ioremap(unsigned long phys_addr,unsigned long size)12*4882a593Smuzhiyunvoid __iomem *ioremap(unsigned long phys_addr, unsigned long size) 13*4882a593Smuzhiyun { 14*4882a593Smuzhiyun unsigned long last_addr, addr; 15*4882a593Smuzhiyun unsigned long offset = phys_addr & ~PAGE_MASK; 16*4882a593Smuzhiyun struct vm_struct *area; 17*4882a593Smuzhiyun 18*4882a593Smuzhiyun pgprot_t prot = __pgprot(_PAGE_PRESENT|_PAGE_READ|_PAGE_WRITE 19*4882a593Smuzhiyun |(__HEXAGON_C_DEV << 6)); 20*4882a593Smuzhiyun 21*4882a593Smuzhiyun last_addr = phys_addr + size - 1; 22*4882a593Smuzhiyun 23*4882a593Smuzhiyun /* Wrapping not allowed */ 24*4882a593Smuzhiyun if (!size || (last_addr < phys_addr)) 25*4882a593Smuzhiyun return NULL; 26*4882a593Smuzhiyun 27*4882a593Smuzhiyun /* Rounds up to next page size, including whole-page offset */ 28*4882a593Smuzhiyun size = PAGE_ALIGN(offset + size); 29*4882a593Smuzhiyun 30*4882a593Smuzhiyun area = get_vm_area(size, VM_IOREMAP); 31*4882a593Smuzhiyun addr = (unsigned long)area->addr; 32*4882a593Smuzhiyun 33*4882a593Smuzhiyun if (ioremap_page_range(addr, addr+size, phys_addr, prot)) { 34*4882a593Smuzhiyun vunmap((void *)addr); 35*4882a593Smuzhiyun return NULL; 36*4882a593Smuzhiyun } 37*4882a593Smuzhiyun 38*4882a593Smuzhiyun return (void __iomem *) (offset + addr); 39*4882a593Smuzhiyun } 40*4882a593Smuzhiyun iounmap(const volatile void __iomem * addr)41*4882a593Smuzhiyunvoid iounmap(const volatile void __iomem *addr) 42*4882a593Smuzhiyun { 43*4882a593Smuzhiyun vunmap((void *) ((unsigned long) addr & PAGE_MASK)); 44*4882a593Smuzhiyun } 45