diff options
author | Paul Mundt <lethal@linux-sh.org> | 2009-08-15 09:19:19 +0900 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2009-08-15 09:19:19 +0900 |
commit | 2739742c24f1a55365e71f0722bfdce8994e9c4e (patch) | |
tree | 2650b2a8aa4113437cc3590c57b4fae98fc25c5b | |
parent | 8edcfcbbd131a3580db666ed1034c24d56eb6f5d (diff) |
sh: Provide the kmap_coherent() interface generically.
This plugs in kmap_coherent() for the non-SH4 cases to permit the
pg-mmu.c bits to be used generically across all CPUs. SH-5 is still in
the TODO state, but will move over to fixmap and the generic interface
gradually.
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
-rw-r--r-- | arch/sh/include/asm/cacheflush.h | 4 | ||||
-rw-r--r-- | arch/sh/include/asm/pgtable.h | 6 | ||||
-rw-r--r-- | arch/sh/mm/Makefile_32 | 2 | ||||
-rw-r--r-- | arch/sh/mm/cache-sh5.c | 15 | ||||
-rw-r--r-- | arch/sh/mm/kmap.c | 64 | ||||
-rw-r--r-- | arch/sh/mm/pg-mmu.c | 48 | ||||
-rw-r--r-- | arch/sh/mm/tlb-nommu.c | 15 |
7 files changed, 99 insertions, 55 deletions
diff --git a/arch/sh/include/asm/cacheflush.h b/arch/sh/include/asm/cacheflush.h index 5dffbd126e4..0e87e87cc01 100644 --- a/arch/sh/include/asm/cacheflush.h +++ b/arch/sh/include/asm/cacheflush.h @@ -74,5 +74,9 @@ extern void copy_from_user_page(struct vm_area_struct *vma, #define flush_cache_vmap(start, end) flush_cache_all() #define flush_cache_vunmap(start, end) flush_cache_all() +void kmap_coherent_init(void); +void *kmap_coherent(struct page *page, unsigned long addr); +void kunmap_coherent(void); + #endif /* __KERNEL__ */ #endif /* __ASM_SH_CACHEFLUSH_H */ diff --git a/arch/sh/include/asm/pgtable.h b/arch/sh/include/asm/pgtable.h index 3cd7127af95..4f3efa7d5a6 100644 --- a/arch/sh/include/asm/pgtable.h +++ b/arch/sh/include/asm/pgtable.h @@ -158,12 +158,6 @@ extern void paging_init(void); extern void page_table_range_init(unsigned long start, unsigned long end, pgd_t *pgd); -#if defined(CONFIG_MMU) && !defined(CONFIG_CPU_SH5) -extern void kmap_coherent_init(void); -#else -#define kmap_coherent_init() do { } while (0) -#endif - /* arch/sh/mm/mmap.c */ #define HAVE_ARCH_UNMAPPED_AREA #define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN diff --git a/arch/sh/mm/Makefile_32 b/arch/sh/mm/Makefile_32 index 17b02522214..30771b137f4 100644 --- a/arch/sh/mm/Makefile_32 +++ b/arch/sh/mm/Makefile_32 @@ -15,7 +15,7 @@ endif obj-y += $(cache-y) mmu-y := tlb-nommu.o pg-nommu.o -mmu-$(CONFIG_MMU) := fault_32.o tlbflush_32.o ioremap_32.o pg-mmu.o +mmu-$(CONFIG_MMU) := fault_32.o kmap.o tlbflush_32.o ioremap_32.o pg-mmu.o obj-y += $(mmu-y) obj-$(CONFIG_DEBUG_FS) += asids-debugfs.o diff --git a/arch/sh/mm/cache-sh5.c b/arch/sh/mm/cache-sh5.c index 698113fce81..28f3c8fb1b9 100644 --- a/arch/sh/mm/cache-sh5.c +++ b/arch/sh/mm/cache-sh5.c @@ -29,6 +29,21 @@ void __init p3_cache_init(void) dtlb_cache_slot = sh64_get_wired_dtlb_entry(); } +void __init kmap_coherent_init(void) +{ + /* XXX ... */ +} + +void *kmap_coherent(struct page *page, unsigned long addr) +{ + /* XXX ... */ + return NULL; +} + +void kunmap_coherent(void) +{ +} + #ifdef CONFIG_DCACHE_DISABLED #define sh64_dcache_purge_all() do { } while (0) #define sh64_dcache_purge_coloured_phy_page(paddr, eaddr) do { } while (0) diff --git a/arch/sh/mm/kmap.c b/arch/sh/mm/kmap.c new file mode 100644 index 00000000000..3eecf0d42f1 --- /dev/null +++ b/arch/sh/mm/kmap.c @@ -0,0 +1,64 @@ +/* + * arch/sh/mm/kmap.c + * + * Copyright (C) 1999, 2000, 2002 Niibe Yutaka + * Copyright (C) 2002 - 2009 Paul Mundt + * + * Released under the terms of the GNU GPL v2.0. + */ +#include <linux/mm.h> +#include <linux/init.h> +#include <linux/mutex.h> +#include <linux/fs.h> +#include <linux/highmem.h> +#include <linux/module.h> +#include <asm/mmu_context.h> +#include <asm/cacheflush.h> + +#define kmap_get_fixmap_pte(vaddr) \ + pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr)), (vaddr)) + +static pte_t *kmap_coherent_pte; + +void __init kmap_coherent_init(void) +{ + unsigned long vaddr; + + if (!boot_cpu_data.dcache.n_aliases) + return; + + /* cache the first coherent kmap pte */ + vaddr = __fix_to_virt(FIX_CMAP_BEGIN); + kmap_coherent_pte = kmap_get_fixmap_pte(vaddr); +} + +void *kmap_coherent(struct page *page, unsigned long addr) +{ + enum fixed_addresses idx; + unsigned long vaddr, flags; + pte_t pte; + + BUG_ON(test_bit(PG_dcache_dirty, &page->flags)); + + inc_preempt_count(); + + idx = (addr & current_cpu_data.dcache.alias_mask) >> PAGE_SHIFT; + vaddr = __fix_to_virt(FIX_CMAP_END - idx); + pte = mk_pte(page, PAGE_KERNEL); + + local_irq_save(flags); + flush_tlb_one(get_asid(), vaddr); + local_irq_restore(flags); + + update_mmu_cache(NULL, vaddr, pte); + + set_pte(kmap_coherent_pte - (FIX_CMAP_END - idx), pte); + + return (void *)vaddr; +} + +void kunmap_coherent(void) +{ + dec_preempt_count(); + preempt_check_resched(); +} diff --git a/arch/sh/mm/pg-mmu.c b/arch/sh/mm/pg-mmu.c index 7a6ef34bd49..f51d0a4eb3b 100644 --- a/arch/sh/mm/pg-mmu.c +++ b/arch/sh/mm/pg-mmu.c @@ -15,54 +15,6 @@ #include <asm/mmu_context.h> #include <asm/cacheflush.h> -#define kmap_get_fixmap_pte(vaddr) \ - pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr)), (vaddr)) - -static pte_t *kmap_coherent_pte; - -void __init kmap_coherent_init(void) -{ - unsigned long vaddr; - - if (!boot_cpu_data.dcache.n_aliases) - return; - - /* cache the first coherent kmap pte */ - vaddr = __fix_to_virt(FIX_CMAP_BEGIN); - kmap_coherent_pte = kmap_get_fixmap_pte(vaddr); -} - -static void *kmap_coherent(struct page *page, unsigned long addr) -{ - enum fixed_addresses idx; - unsigned long vaddr, flags; - pte_t pte; - - BUG_ON(test_bit(PG_dcache_dirty, &page->flags)); - - inc_preempt_count(); - - idx = (addr & current_cpu_data.dcache.alias_mask) >> PAGE_SHIFT; - vaddr = __fix_to_virt(FIX_CMAP_END - idx); - pte = mk_pte(page, PAGE_KERNEL); - - local_irq_save(flags); - flush_tlb_one(get_asid(), vaddr); - local_irq_restore(flags); - - update_mmu_cache(NULL, vaddr, pte); - - set_pte(kmap_coherent_pte - (FIX_CMAP_END - idx), pte); - - return (void *)vaddr; -} - -static inline void kunmap_coherent(void) -{ - dec_preempt_count(); - preempt_check_resched(); -} - void copy_to_user_page(struct vm_area_struct *vma, struct page *page, unsigned long vaddr, void *dst, const void *src, unsigned long len) diff --git a/arch/sh/mm/tlb-nommu.c b/arch/sh/mm/tlb-nommu.c index 0ef5429943d..c49e9d24c2e 100644 --- a/arch/sh/mm/tlb-nommu.c +++ b/arch/sh/mm/tlb-nommu.c @@ -55,6 +55,21 @@ void __update_cache(struct vm_area_struct *vma, { } +void __init kmap_coherent_init(void) +{ +} + +void *kmap_coherent(struct page *page, unsigned long addr) +{ + BUG(); + return NULL; +} + +void kunmap_coherent(void) +{ + BUG(); +} + void __init page_table_range_init(unsigned long start, unsigned long end, pgd_t *pgd_base) { |