Pull cpuidle into release branch
[pandora-kernel.git] / arch / mips / mm / tlb-r4k.c
index 2e0e21e..74ae034 100644 (file)
@@ -48,6 +48,22 @@ extern void build_tlb_refill_handler(void);
 
 #endif /* CONFIG_MIPS_MT_SMTC */
 
+#if defined(CONFIG_CPU_LOONGSON2)
+/*
+ * LOONGSON2 has a 4 entry itlb which is a subset of dtlb,
+ * unfortrunately, itlb is not totally transparent to software.
+ */
+#define FLUSH_ITLB write_c0_diag(4);
+
+#define FLUSH_ITLB_VM(vma) { if ((vma)->vm_flags & VM_EXEC)  write_c0_diag(4); }
+
+#else
+
+#define FLUSH_ITLB
+#define FLUSH_ITLB_VM(vma)
+
+#endif
+
 void local_flush_tlb_all(void)
 {
        unsigned long flags;
@@ -73,6 +89,7 @@ void local_flush_tlb_all(void)
        }
        tlbw_use_hazard();
        write_c0_entryhi(old_ctx);
+       FLUSH_ITLB;
        EXIT_CRITICAL(flags);
 }
 
@@ -106,7 +123,6 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
                ENTER_CRITICAL(flags);
                size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
                size = (size + 1) >> 1;
-               local_irq_save(flags);
                if (size <= current_cpu_data.tlbsize/2) {
                        int oldpid = read_c0_entryhi();
                        int newpid = cpu_asid(cpu, mm);
@@ -137,6 +153,7 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
                } else {
                        drop_mmu_context(mm, cpu);
                }
+               FLUSH_ITLB;
                EXIT_CRITICAL(flags);
        }
 }
@@ -179,6 +196,7 @@ void local_flush_tlb_kernel_range(unsigned long start, unsigned long end)
        } else {
                local_flush_tlb_all();
        }
+       FLUSH_ITLB;
        EXIT_CRITICAL(flags);
 }
 
@@ -211,6 +229,7 @@ void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
 
        finish:
                write_c0_entryhi(oldpid);
+               FLUSH_ITLB_VM(vma);
                EXIT_CRITICAL(flags);
        }
 }
@@ -242,7 +261,7 @@ void local_flush_tlb_one(unsigned long page)
                tlbw_use_hazard();
        }
        write_c0_entryhi(oldpid);
-
+       FLUSH_ITLB;
        EXIT_CRITICAL(flags);
 }
 
@@ -294,6 +313,7 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte)
        else
                tlb_write_indexed();
        tlbw_use_hazard();
+       FLUSH_ITLB_VM(vma);
        EXIT_CRITICAL(flags);
 }
 
@@ -471,7 +491,7 @@ void __init tlb_init(void)
                        int wired = current_cpu_data.tlbsize - ntlb;
                        write_c0_wired(wired);
                        write_c0_index(wired-1);
-                       printk ("Restricting TLB to %d entries\n", ntlb);
+                       printk("Restricting TLB to %d entries\n", ntlb);
                } else
                        printk("Ignoring invalid argument ntlb=%d\n", ntlb);
        }