~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/lib/ioremap.c

Version: ~ [ linux-5.5 ] ~ [ linux-5.4.15 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.98 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.167 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.211 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.211 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.81 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * Re-map IO memory to kernel address space so that we can access it.
  3  * This is needed for high PCI addresses that aren't mapped in the
  4  * 640k-1MB IO memory area on PC's
  5  *
  6  * (C) Copyright 1995 1996 Linus Torvalds
  7  */
  8 #include <linux/vmalloc.h>
  9 #include <linux/mm.h>
 10 #include <linux/sched.h>
 11 #include <linux/io.h>
 12 #include <linux/export.h>
 13 #include <asm/cacheflush.h>
 14 #include <asm/pgtable.h>
 15 
 16 static int ioremap_pte_range(pmd_t *pmd, unsigned long addr,
 17                 unsigned long end, phys_addr_t phys_addr, pgprot_t prot)
 18 {
 19         pte_t *pte;
 20         u64 pfn;
 21 
 22         pfn = phys_addr >> PAGE_SHIFT;
 23         pte = pte_alloc_kernel(pmd, addr);
 24         if (!pte)
 25                 return -ENOMEM;
 26         do {
 27                 BUG_ON(!pte_none(*pte));
 28                 set_pte_at(&init_mm, addr, pte, pfn_pte(pfn, prot));
 29                 pfn++;
 30         } while (pte++, addr += PAGE_SIZE, addr != end);
 31         return 0;
 32 }
 33 
 34 static inline int ioremap_pmd_range(pud_t *pud, unsigned long addr,
 35                 unsigned long end, phys_addr_t phys_addr, pgprot_t prot)
 36 {
 37         pmd_t *pmd;
 38         unsigned long next;
 39 
 40         phys_addr -= addr;
 41         pmd = pmd_alloc(&init_mm, pud, addr);
 42         if (!pmd)
 43                 return -ENOMEM;
 44         do {
 45                 next = pmd_addr_end(addr, end);
 46                 if (ioremap_pte_range(pmd, addr, next, phys_addr + addr, prot))
 47                         return -ENOMEM;
 48         } while (pmd++, addr = next, addr != end);
 49         return 0;
 50 }
 51 
 52 static inline int ioremap_pud_range(pgd_t *pgd, unsigned long addr,
 53                 unsigned long end, phys_addr_t phys_addr, pgprot_t prot)
 54 {
 55         pud_t *pud;
 56         unsigned long next;
 57 
 58         phys_addr -= addr;
 59         pud = pud_alloc(&init_mm, pgd, addr);
 60         if (!pud)
 61                 return -ENOMEM;
 62         do {
 63                 next = pud_addr_end(addr, end);
 64                 if (ioremap_pmd_range(pud, addr, next, phys_addr + addr, prot))
 65                         return -ENOMEM;
 66         } while (pud++, addr = next, addr != end);
 67         return 0;
 68 }
 69 
 70 int ioremap_page_range(unsigned long addr,
 71                        unsigned long end, phys_addr_t phys_addr, pgprot_t prot)
 72 {
 73         pgd_t *pgd;
 74         unsigned long start;
 75         unsigned long next;
 76         int err;
 77 
 78         BUG_ON(addr >= end);
 79 
 80         start = addr;
 81         phys_addr -= addr;
 82         pgd = pgd_offset_k(addr);
 83         do {
 84                 next = pgd_addr_end(addr, end);
 85                 err = ioremap_pud_range(pgd, addr, next, phys_addr+addr, prot);
 86                 if (err)
 87                         break;
 88         } while (pgd++, addr = next, addr != end);
 89 
 90         flush_cache_vmap(start, end);
 91 
 92         return err;
 93 }
 94 EXPORT_SYMBOL_GPL(ioremap_page_range);
 95 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp