From 760146bd9b1773297cedb423c24e0e921324ffa4 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Tue, 17 Nov 2009 22:03:41 +0000 Subject: [PATCH] --- yaml --- r: 181097 b: refs/heads/master c: 07cad4dc1bfdaefd20c6329e9d8179ad1c600e92 h: refs/heads/master i: 181095: 03c1e883aba3c150eff369d1c2fba0970e1e2927 v: v3 --- [refs] | 2 +- trunk/arch/sh/include/asm/fixmap.h | 1 + trunk/arch/sh/mm/init.c | 44 +++++++++++++++++++++++++++--- 3 files changed, 42 insertions(+), 5 deletions(-) diff --git a/[refs] b/[refs] index 021e879bfdb9..7bb46583e140 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 24ef7fc4dcc57afa0c33166c25bfe7676ffd4296 +refs/heads/master: 07cad4dc1bfdaefd20c6329e9d8179ad1c600e92 diff --git a/trunk/arch/sh/include/asm/fixmap.h b/trunk/arch/sh/include/asm/fixmap.h index 5ac1e40a511c..1566d3361ca4 100644 --- a/trunk/arch/sh/include/asm/fixmap.h +++ b/trunk/arch/sh/include/asm/fixmap.h @@ -65,6 +65,7 @@ enum fixed_addresses { extern void __set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t flags); +extern void __clear_fixmap(enum fixed_addresses idx, pgprot_t flags); #define set_fixmap(idx, phys) \ __set_fixmap(idx, phys, PAGE_KERNEL) diff --git a/trunk/arch/sh/mm/init.c b/trunk/arch/sh/mm/init.c index d5fb014279ad..30a9b530d456 100644 --- a/trunk/arch/sh/mm/init.c +++ b/trunk/arch/sh/mm/init.c @@ -39,7 +39,7 @@ unsigned long cached_to_uncached = P2SEG - P1SEG; #endif #ifdef CONFIG_MMU -static void set_pte_phys(unsigned long addr, unsigned long phys, pgprot_t prot) +static pte_t *__get_pte_phys(unsigned long addr) { pgd_t *pgd; pud_t *pud; @@ -49,22 +49,30 @@ static void set_pte_phys(unsigned long addr, unsigned long phys, pgprot_t prot) pgd = pgd_offset_k(addr); if (pgd_none(*pgd)) { pgd_ERROR(*pgd); - return; + return NULL; } pud = pud_alloc(NULL, pgd, addr); if (unlikely(!pud)) { pud_ERROR(*pud); - return; + return NULL; } pmd = pmd_alloc(NULL, pud, addr); if (unlikely(!pmd)) { pmd_ERROR(*pmd); - return; + return NULL; } pte = pte_offset_kernel(pmd, addr); + return pte; +} + +static void set_pte_phys(unsigned long addr, unsigned long phys, pgprot_t prot) +{ + pte_t *pte; + + pte = __get_pte_phys(addr); if (!pte_none(*pte)) { pte_ERROR(*pte); return; @@ -72,6 +80,22 @@ static void set_pte_phys(unsigned long addr, unsigned long phys, pgprot_t prot) set_pte(pte, pfn_pte(phys >> PAGE_SHIFT, prot)); local_flush_tlb_one(get_asid(), addr); + + if (pgprot_val(prot) & _PAGE_WIRED) + tlb_wire_entry(NULL, addr, *pte); +} + +static void clear_pte_phys(unsigned long addr, pgprot_t prot) +{ + pte_t *pte; + + pte = __get_pte_phys(addr); + + if (pgprot_val(prot) & _PAGE_WIRED) + tlb_unwire_entry(); + + set_pte(pte, pfn_pte(0, __pgprot(0))); + local_flush_tlb_one(get_asid(), addr); } /* @@ -101,6 +125,18 @@ void __set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t prot) set_pte_phys(address, phys, prot); } +void __clear_fixmap(enum fixed_addresses idx, pgprot_t prot) +{ + unsigned long address = __fix_to_virt(idx); + + if (idx >= __end_of_fixed_addresses) { + BUG(); + return; + } + + clear_pte_phys(address, prot); +} + void __init page_table_range_init(unsigned long start, unsigned long end, pgd_t *pgd_base) {