diff options
Diffstat (limited to 'arch/parisc/kernel/cache.c')
-rw-r--r-- | arch/parisc/kernel/cache.c | 48 |
1 files changed, 44 insertions, 4 deletions
diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c index bc7c4a4e26a..0be51e92a2f 100644 --- a/arch/parisc/kernel/cache.c +++ b/arch/parisc/kernel/cache.c @@ -35,15 +35,12 @@ int icache_stride __read_mostly; EXPORT_SYMBOL(dcache_stride); -#if defined(CONFIG_SMP) /* On some machines (e.g. ones with the Merced bus), there can be * only a single PxTLB broadcast at a time; this must be guaranteed * by software. We put a spinlock around all TLB flushes to * ensure this. */ DEFINE_SPINLOCK(pa_tlb_lock); -EXPORT_SYMBOL(pa_tlb_lock); -#endif struct pdc_cache_info cache_info __read_mostly; #ifndef CONFIG_PA20 @@ -91,7 +88,8 @@ update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t pte) flush_kernel_dcache_page(page); clear_bit(PG_dcache_dirty, &page->flags); - } + } else if (parisc_requires_coherency()) + flush_kernel_dcache_page(page); } void @@ -370,3 +368,45 @@ void parisc_setup_cache_timing(void) printk(KERN_INFO "Setting cache flush threshold to %x (%d CPUs online)\n", parisc_cache_flush_threshold, num_online_cpus()); } + +extern void purge_kernel_dcache_page(unsigned long); +extern void clear_user_page_asm(void *page, unsigned long vaddr); + +void clear_user_page(void *page, unsigned long vaddr, struct page *pg) +{ + purge_kernel_dcache_page((unsigned long)page); + purge_tlb_start(); + pdtlb_kernel(page); + purge_tlb_end(); + clear_user_page_asm(page, vaddr); +} +EXPORT_SYMBOL(clear_user_page); + +void flush_kernel_dcache_page_addr(void *addr) +{ + flush_kernel_dcache_page_asm(addr); + purge_tlb_start(); + pdtlb_kernel(addr); + purge_tlb_end(); +} +EXPORT_SYMBOL(flush_kernel_dcache_page_addr); + +void copy_user_page(void *vto, void *vfrom, unsigned long vaddr, + struct page *pg) +{ + /* no coherency needed (all in kmap/kunmap) */ + copy_user_page_asm(vto, vfrom); + if (!parisc_requires_coherency()) + flush_kernel_dcache_page_asm(vto); +} +EXPORT_SYMBOL(copy_user_page); + +#ifdef CONFIG_PA8X00 + +void kunmap_parisc(void *addr) +{ + if (parisc_requires_coherency()) + flush_kernel_dcache_page_addr(addr); +} +EXPORT_SYMBOL(kunmap_parisc); +#endif |