linux/arch/xtensa/mm/ioremap.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * ioremap implementation.
   4 *
   5 * Copyright (C) 2015 Cadence Design Systems Inc.
   6 */
   7
   8#include <linux/io.h>
   9#include <linux/vmalloc.h>
  10#include <linux/pgtable.h>
  11#include <asm/cacheflush.h>
  12#include <asm/io.h>
  13
  14static void __iomem *xtensa_ioremap(unsigned long paddr, unsigned long size,
  15                                    pgprot_t prot)
  16{
  17        unsigned long offset = paddr & ~PAGE_MASK;
  18        unsigned long pfn = __phys_to_pfn(paddr);
  19        struct vm_struct *area;
  20        unsigned long vaddr;
  21        int err;
  22
  23        paddr &= PAGE_MASK;
  24
  25        WARN_ON(pfn_valid(pfn));
  26
  27        size = PAGE_ALIGN(offset + size);
  28
  29        area = get_vm_area(size, VM_IOREMAP);
  30        if (!area)
  31                return NULL;
  32
  33        vaddr = (unsigned long)area->addr;
  34        area->phys_addr = paddr;
  35
  36        err = ioremap_page_range(vaddr, vaddr + size, paddr, prot);
  37
  38        if (err) {
  39                vunmap((void *)vaddr);
  40                return NULL;
  41        }
  42
  43        flush_cache_vmap(vaddr, vaddr + size);
  44        return (void __iomem *)(offset + vaddr);
  45}
  46
  47void __iomem *xtensa_ioremap_nocache(unsigned long addr, unsigned long size)
  48{
  49        return xtensa_ioremap(addr, size, pgprot_noncached(PAGE_KERNEL));
  50}
  51EXPORT_SYMBOL(xtensa_ioremap_nocache);
  52
  53void __iomem *xtensa_ioremap_cache(unsigned long addr, unsigned long size)
  54{
  55        return xtensa_ioremap(addr, size, PAGE_KERNEL);
  56}
  57EXPORT_SYMBOL(xtensa_ioremap_cache);
  58
  59void xtensa_iounmap(volatile void __iomem *io_addr)
  60{
  61        void *addr = (void *)(PAGE_MASK & (unsigned long)io_addr);
  62
  63        vunmap(addr);
  64}
  65EXPORT_SYMBOL(xtensa_iounmap);
  66