OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [lib/] [ioremap.c] - Blame information for rev 62

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/*
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 <asm/cacheflush.h>
13
#include <asm/pgtable.h>
14
 
15
static int ioremap_pte_range(pmd_t *pmd, unsigned long addr,
16
                unsigned long end, unsigned long phys_addr, pgprot_t prot)
17
{
18
        pte_t *pte;
19
        unsigned long pfn;
20
 
21
        pfn = phys_addr >> PAGE_SHIFT;
22
        pte = pte_alloc_kernel(pmd, addr);
23
        if (!pte)
24
                return -ENOMEM;
25
        do {
26
                BUG_ON(!pte_none(*pte));
27
                set_pte_at(&init_mm, addr, pte, pfn_pte(pfn, prot));
28
                pfn++;
29
        } while (pte++, addr += PAGE_SIZE, addr != end);
30
        return 0;
31
}
32
 
33
static inline int ioremap_pmd_range(pud_t *pud, unsigned long addr,
34
                unsigned long end, unsigned long phys_addr, pgprot_t prot)
35
{
36
        pmd_t *pmd;
37
        unsigned long next;
38
 
39
        phys_addr -= addr;
40
        pmd = pmd_alloc(&init_mm, pud, addr);
41
        if (!pmd)
42
                return -ENOMEM;
43
        do {
44
                next = pmd_addr_end(addr, end);
45
                if (ioremap_pte_range(pmd, addr, next, phys_addr + addr, prot))
46
                        return -ENOMEM;
47
        } while (pmd++, addr = next, addr != end);
48
        return 0;
49
}
50
 
51
static inline int ioremap_pud_range(pgd_t *pgd, unsigned long addr,
52
                unsigned long end, unsigned long phys_addr, pgprot_t prot)
53
{
54
        pud_t *pud;
55
        unsigned long next;
56
 
57
        phys_addr -= addr;
58
        pud = pud_alloc(&init_mm, pgd, addr);
59
        if (!pud)
60
                return -ENOMEM;
61
        do {
62
                next = pud_addr_end(addr, end);
63
                if (ioremap_pmd_range(pud, addr, next, phys_addr + addr, prot))
64
                        return -ENOMEM;
65
        } while (pud++, addr = next, addr != end);
66
        return 0;
67
}
68
 
69
int ioremap_page_range(unsigned long addr,
70
                       unsigned long end, unsigned long phys_addr, pgprot_t prot)
71
{
72
        pgd_t *pgd;
73
        unsigned long start;
74
        unsigned long next;
75
        int err;
76
 
77
        BUG_ON(addr >= end);
78
 
79
        start = addr;
80
        phys_addr -= addr;
81
        pgd = pgd_offset_k(addr);
82
        do {
83
                next = pgd_addr_end(addr, end);
84
                err = ioremap_pud_range(pgd, addr, next, phys_addr+addr, prot);
85
                if (err)
86
                        break;
87
        } while (pgd++, addr = next, addr != end);
88
 
89
        flush_cache_vmap(start, end);
90
 
91
        return err;
92
}

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.