/*1* arch/cris/mm/ioremap.c2*3* Re-map IO memory to kernel address space so that we can access it.4* Needed for memory-mapped I/O devices mapped outside our normal DRAM5* window (that is, all memory-mapped I/O devices).6*7* (C) Copyright 1995 1996 Linus Torvalds8* CRIS-port by Axis Communications AB9*/1011#include <linux/vmalloc.h>12#include <linux/io.h>13#include <asm/pgalloc.h>14#include <arch/memmap.h>1516/*17* Generic mapping function (not visible outside):18*/1920/*21* Remap an arbitrary physical address space into the kernel virtual22* address space. Needed when the kernel wants to access high addresses23* directly.24*25* NOTE! We need to allow non-page-aligned mappings too: we will obviously26* have to convert them into an offset in a page-aligned mapping, but the27* caller shouldn't need to know that small detail.28*/29void __iomem * __ioremap_prot(unsigned long phys_addr, unsigned long size, pgprot_t prot)30{31void __iomem * addr;32struct vm_struct * area;33unsigned long offset, last_addr;3435/* Don't allow wraparound or zero size */36last_addr = phys_addr + size - 1;37if (!size || last_addr < phys_addr)38return NULL;3940/*41* Mappings have to be page-aligned42*/43offset = phys_addr & ~PAGE_MASK;44phys_addr &= PAGE_MASK;45size = PAGE_ALIGN(last_addr+1) - phys_addr;4647/*48* Ok, go for it..49*/50area = get_vm_area(size, VM_IOREMAP);51if (!area)52return NULL;53addr = (void __iomem *)area->addr;54if (ioremap_page_range((unsigned long)addr, (unsigned long)addr + size,55phys_addr, prot)) {56vfree((void __force *)addr);57return NULL;58}59return (void __iomem *) (offset + (char __iomem *)addr);60}6162void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags)63{64return __ioremap_prot(phys_addr, size,65__pgprot(_PAGE_PRESENT | __READABLE |66__WRITEABLE | _PAGE_GLOBAL |67_PAGE_KERNEL | flags));68}6970/**71* ioremap_nocache - map bus memory into CPU space72* @offset: bus address of the memory73* @size: size of the resource to map74*75* Must be freed with iounmap.76*/7778void __iomem *ioremap_nocache (unsigned long phys_addr, unsigned long size)79{80return __ioremap(phys_addr | MEM_NON_CACHEABLE, size, 0);81}8283void iounmap(volatile void __iomem *addr)84{85if (addr > high_memory)86return vfree((void *) (PAGE_MASK & (unsigned long) addr));87}888990