[PATCH] ppc32: defconfig for Marvell EV64360BP board
[linux-3.10.git] / arch / ppc / mm / init.c
index 334ef41..f421a4b 100644 (file)
@@ -560,8 +560,12 @@ void flush_dcache_page(struct page *page)
 void flush_dcache_icache_page(struct page *page)
 {
 #ifdef CONFIG_BOOKE
-       __flush_dcache_icache(kmap(page));
-       kunmap(page);
+       void *start = kmap_atomic(page, KM_PPC_SYNC_ICACHE);
+       __flush_dcache_icache(start);
+       kunmap_atomic(start, KM_PPC_SYNC_ICACHE);
+#elif defined(CONFIG_8xx)
+       /* On 8xx there is no need to kmap since highmem is not supported */
+       __flush_dcache_icache(page_address(page)); 
 #else
        __flush_dcache_icache_phys(page_to_pfn(page) << PAGE_SHIFT);
 #endif
@@ -606,9 +610,19 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address,
                struct page *page = pfn_to_page(pfn);
                if (!PageReserved(page)
                    && !test_bit(PG_arch_1, &page->flags)) {
-                       if (vma->vm_mm == current->active_mm)
+                       if (vma->vm_mm == current->active_mm) {
+#ifdef CONFIG_8xx
+                       /* On 8xx, cache control instructions (particularly 
+                        * "dcbst" from flush_dcache_icache) fault as write 
+                        * operation if there is an unpopulated TLB entry 
+                        * for the address in question. To workaround that, 
+                        * we invalidate the TLB here, thus avoiding dcbst 
+                        * misbehaviour.
+                        */
+                               _tlbie(address);
+#endif
                                __flush_dcache_icache((void *) address);
-                       else
+                       } else
                                flush_dcache_icache_page(page);
                        set_bit(PG_arch_1, &page->flags);
                }