linux/arch/nds32/mm/highmem.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2// Copyright (C) 2005-2017 Andes Technology Corporation
   3
   4#include <linux/export.h>
   5#include <linux/highmem.h>
   6#include <linux/sched.h>
   7#include <linux/smp.h>
   8#include <linux/interrupt.h>
   9#include <linux/memblock.h>
  10#include <asm/fixmap.h>
  11#include <asm/tlbflush.h>
  12
  13void *kmap(struct page *page)
  14{
  15        unsigned long vaddr;
  16        might_sleep();
  17        if (!PageHighMem(page))
  18                return page_address(page);
  19        vaddr = (unsigned long)kmap_high(page);
  20        return (void *)vaddr;
  21}
  22
  23EXPORT_SYMBOL(kmap);
  24
  25void kunmap(struct page *page)
  26{
  27        BUG_ON(in_interrupt());
  28        if (!PageHighMem(page))
  29                return;
  30        kunmap_high(page);
  31}
  32
  33EXPORT_SYMBOL(kunmap);
  34
  35void *kmap_atomic(struct page *page)
  36{
  37        unsigned int idx;
  38        unsigned long vaddr, pte;
  39        int type;
  40        pte_t *ptep;
  41
  42        preempt_disable();
  43        pagefault_disable();
  44        if (!PageHighMem(page))
  45                return page_address(page);
  46
  47        type = kmap_atomic_idx_push();
  48
  49        idx = type + KM_TYPE_NR * smp_processor_id();
  50        vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
  51        pte = (page_to_pfn(page) << PAGE_SHIFT) | (PAGE_KERNEL);
  52        ptep = pte_offset_kernel(pmd_off_k(vaddr), vaddr);
  53        set_pte(ptep, pte);
  54
  55        __nds32__tlbop_inv(vaddr);
  56        __nds32__mtsr_dsb(vaddr, NDS32_SR_TLB_VPN);
  57        __nds32__tlbop_rwr(pte);
  58        __nds32__isb();
  59        return (void *)vaddr;
  60}
  61
  62EXPORT_SYMBOL(kmap_atomic);
  63
  64void __kunmap_atomic(void *kvaddr)
  65{
  66        if (kvaddr >= (void *)FIXADDR_START) {
  67                unsigned long vaddr = (unsigned long)kvaddr;
  68                pte_t *ptep;
  69                kmap_atomic_idx_pop();
  70                __nds32__tlbop_inv(vaddr);
  71                __nds32__isb();
  72                ptep = pte_offset_kernel(pmd_off_k(vaddr), vaddr);
  73                set_pte(ptep, 0);
  74        }
  75        pagefault_enable();
  76        preempt_enable();
  77}
  78
  79EXPORT_SYMBOL(__kunmap_atomic);
  80