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