aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/mm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/mm')
-rw-r--r--arch/mips/mm/c-r4k.c9
-rw-r--r--arch/mips/mm/cache.c15
-rw-r--r--arch/mips/mm/init.c9
-rw-r--r--arch/mips/mm/pg-sb1.c14
4 files changed, 29 insertions, 18 deletions
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
index 53ec05267a98..2c4f7e11f0d5 100644
--- a/arch/mips/mm/c-r4k.c
+++ b/arch/mips/mm/c-r4k.c
@@ -364,20 +364,23 @@ static inline int has_valid_asid(const struct mm_struct *mm)
364static inline void local_r4k_flush_cache_range(void * args) 364static inline void local_r4k_flush_cache_range(void * args)
365{ 365{
366 struct vm_area_struct *vma = args; 366 struct vm_area_struct *vma = args;
367 int exec = vma->vm_flags & VM_EXEC;
367 368
368 if (!(has_valid_asid(vma->vm_mm))) 369 if (!(has_valid_asid(vma->vm_mm)))
369 return; 370 return;
370 371
371 r4k_blast_dcache(); 372 r4k_blast_dcache();
373 if (exec)
374 r4k_blast_icache();
372} 375}
373 376
374static void r4k_flush_cache_range(struct vm_area_struct *vma, 377static void r4k_flush_cache_range(struct vm_area_struct *vma,
375 unsigned long start, unsigned long end) 378 unsigned long start, unsigned long end)
376{ 379{
377 if (!cpu_has_dc_aliases) 380 int exec = vma->vm_flags & VM_EXEC;
378 return;
379 381
380 r4k_on_each_cpu(local_r4k_flush_cache_range, vma, 1, 1); 382 if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc))
383 r4k_on_each_cpu(local_r4k_flush_cache_range, vma, 1, 1);
381} 384}
382 385
383static inline void local_r4k_flush_cache_mm(void * args) 386static inline void local_r4k_flush_cache_mm(void * args)
diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c
index 81f30ac2bff9..6a24651971df 100644
--- a/arch/mips/mm/cache.c
+++ b/arch/mips/mm/cache.c
@@ -92,12 +92,17 @@ EXPORT_SYMBOL(__flush_dcache_page);
92 92
93void __flush_anon_page(struct page *page, unsigned long vmaddr) 93void __flush_anon_page(struct page *page, unsigned long vmaddr)
94{ 94{
95 if (pages_do_alias((unsigned long)page_address(page), vmaddr)) { 95 unsigned long addr = (unsigned long) page_address(page);
96 void *kaddr;
97 96
98 kaddr = kmap_coherent(page, vmaddr); 97 if (pages_do_alias(addr, vmaddr)) {
99 flush_data_cache_page((unsigned long)kaddr); 98 if (page_mapped(page) && !Page_dcache_dirty(page)) {
100 kunmap_coherent(); 99 void *kaddr;
100
101 kaddr = kmap_coherent(page, vmaddr);
102 flush_data_cache_page((unsigned long)kaddr);
103 kunmap_coherent();
104 } else
105 flush_data_cache_page(addr);
101 } 106 }
102} 107}
103 108
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
index 480dec04f552..c7aed133d11d 100644
--- a/arch/mips/mm/init.c
+++ b/arch/mips/mm/init.c
@@ -211,7 +211,8 @@ void copy_user_highpage(struct page *to, struct page *from,
211 void *vfrom, *vto; 211 void *vfrom, *vto;
212 212
213 vto = kmap_atomic(to, KM_USER1); 213 vto = kmap_atomic(to, KM_USER1);
214 if (cpu_has_dc_aliases && page_mapped(from)) { 214 if (cpu_has_dc_aliases &&
215 page_mapped(from) && !Page_dcache_dirty(from)) {
215 vfrom = kmap_coherent(from, vaddr); 216 vfrom = kmap_coherent(from, vaddr);
216 copy_page(vto, vfrom); 217 copy_page(vto, vfrom);
217 kunmap_coherent(); 218 kunmap_coherent();
@@ -234,7 +235,8 @@ void copy_to_user_page(struct vm_area_struct *vma,
234 struct page *page, unsigned long vaddr, void *dst, const void *src, 235 struct page *page, unsigned long vaddr, void *dst, const void *src,
235 unsigned long len) 236 unsigned long len)
236{ 237{
237 if (cpu_has_dc_aliases && page_mapped(page)) { 238 if (cpu_has_dc_aliases &&
239 page_mapped(page) && !Page_dcache_dirty(page)) {
238 void *vto = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK); 240 void *vto = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK);
239 memcpy(vto, src, len); 241 memcpy(vto, src, len);
240 kunmap_coherent(); 242 kunmap_coherent();
@@ -253,7 +255,8 @@ void copy_from_user_page(struct vm_area_struct *vma,
253 struct page *page, unsigned long vaddr, void *dst, const void *src, 255 struct page *page, unsigned long vaddr, void *dst, const void *src,
254 unsigned long len) 256 unsigned long len)
255{ 257{
256 if (cpu_has_dc_aliases && page_mapped(page)) { 258 if (cpu_has_dc_aliases &&
259 page_mapped(page) && !Page_dcache_dirty(page)) {
257 void *vfrom = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK); 260 void *vfrom = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK);
258 memcpy(dst, vfrom, len); 261 memcpy(dst, vfrom, len);
259 kunmap_coherent(); 262 kunmap_coherent();
diff --git a/arch/mips/mm/pg-sb1.c b/arch/mips/mm/pg-sb1.c
index a3e98c243a89..89925ec57d6a 100644
--- a/arch/mips/mm/pg-sb1.c
+++ b/arch/mips/mm/pg-sb1.c
@@ -216,7 +216,7 @@ void sb1_dma_init(void)
216 int i; 216 int i;
217 217
218 for (i = 0; i < DM_NUM_CHANNELS; i++) { 218 for (i = 0; i < DM_NUM_CHANNELS; i++) {
219 const u64 base_val = CPHYSADDR(&page_descr[i]) | 219 const u64 base_val = CPHYSADDR((unsigned long)&page_descr[i]) |
220 V_DM_DSCR_BASE_RINGSZ(1); 220 V_DM_DSCR_BASE_RINGSZ(1);
221 void *base_reg = IOADDR(A_DM_REGISTER(i, R_DM_DSCR_BASE)); 221 void *base_reg = IOADDR(A_DM_REGISTER(i, R_DM_DSCR_BASE));
222 222
@@ -228,11 +228,11 @@ void sb1_dma_init(void)
228 228
229void clear_page(void *page) 229void clear_page(void *page)
230{ 230{
231 u64 to_phys = CPHYSADDR(page); 231 u64 to_phys = CPHYSADDR((unsigned long)page);
232 unsigned int cpu = smp_processor_id(); 232 unsigned int cpu = smp_processor_id();
233 233
234 /* if the page is not in KSEG0, use old way */ 234 /* if the page is not in KSEG0, use old way */
235 if ((long)KSEGX(page) != (long)CKSEG0) 235 if ((long)KSEGX((unsigned long)page) != (long)CKSEG0)
236 return clear_page_cpu(page); 236 return clear_page_cpu(page);
237 237
238 page_descr[cpu].dscr_a = to_phys | M_DM_DSCRA_ZERO_MEM | 238 page_descr[cpu].dscr_a = to_phys | M_DM_DSCRA_ZERO_MEM |
@@ -252,13 +252,13 @@ void clear_page(void *page)
252 252
253void copy_page(void *to, void *from) 253void copy_page(void *to, void *from)
254{ 254{
255 u64 from_phys = CPHYSADDR(from); 255 u64 from_phys = CPHYSADDR((unsigned long)from);
256 u64 to_phys = CPHYSADDR(to); 256 u64 to_phys = CPHYSADDR((unsigned long)to);
257 unsigned int cpu = smp_processor_id(); 257 unsigned int cpu = smp_processor_id();
258 258
259 /* if any page is not in KSEG0, use old way */ 259 /* if any page is not in KSEG0, use old way */
260 if ((long)KSEGX(to) != (long)CKSEG0 260 if ((long)KSEGX((unsigned long)to) != (long)CKSEG0
261 || (long)KSEGX(from) != (long)CKSEG0) 261 || (long)KSEGX((unsigned long)from) != (long)CKSEG0)
262 return copy_page_cpu(to, from); 262 return copy_page_cpu(to, from);
263 263
264 page_descr[cpu].dscr_a = to_phys | M_DM_DSCRA_L2C_DEST | 264 page_descr[cpu].dscr_a = to_phys | M_DM_DSCRA_L2C_DEST |