xref: /openbmc/linux/arch/csky/abiv1/cacheflush.c (revision 55fd7e02)
1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
3 
4 #include <linux/kernel.h>
5 #include <linux/mm.h>
6 #include <linux/fs.h>
7 #include <linux/syscalls.h>
8 #include <linux/spinlock.h>
9 #include <asm/page.h>
10 #include <asm/cache.h>
11 #include <asm/cacheflush.h>
12 #include <asm/cachectl.h>
13 
14 #define PG_dcache_clean		PG_arch_1
15 
16 void flush_dcache_page(struct page *page)
17 {
18 	struct address_space *mapping;
19 
20 	if (page == ZERO_PAGE(0))
21 		return;
22 
23 	mapping = page_mapping_file(page);
24 
25 	if (mapping && !page_mapcount(page))
26 		clear_bit(PG_dcache_clean, &page->flags);
27 	else {
28 		dcache_wbinv_all();
29 		if (mapping)
30 			icache_inv_all();
31 		set_bit(PG_dcache_clean, &page->flags);
32 	}
33 }
34 EXPORT_SYMBOL(flush_dcache_page);
35 
36 void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr,
37 	pte_t *ptep)
38 {
39 	unsigned long pfn = pte_pfn(*ptep);
40 	struct page *page;
41 
42 	if (!pfn_valid(pfn))
43 		return;
44 
45 	page = pfn_to_page(pfn);
46 	if (page == ZERO_PAGE(0))
47 		return;
48 
49 	if (!test_and_set_bit(PG_dcache_clean, &page->flags))
50 		dcache_wbinv_all();
51 
52 	if (page_mapping_file(page)) {
53 		if (vma->vm_flags & VM_EXEC)
54 			icache_inv_all();
55 	}
56 }
57 
58 void flush_kernel_dcache_page(struct page *page)
59 {
60 	struct address_space *mapping;
61 
62 	mapping = page_mapping_file(page);
63 
64 	if (!mapping || mapping_mapped(mapping))
65 		dcache_wbinv_all();
66 }
67 EXPORT_SYMBOL(flush_kernel_dcache_page);
68 
69 void flush_cache_range(struct vm_area_struct *vma, unsigned long start,
70 	unsigned long end)
71 {
72 	dcache_wbinv_all();
73 
74 	if (vma->vm_flags & VM_EXEC)
75 		icache_inv_all();
76 }
77