Merge branch 'linus' into cpus4096
[pandora-kernel.git] / arch / mips / kernel / smtc.c
index a8c1a69..a516286 100644 (file)
@@ -16,7 +16,6 @@
 #include <asm/hazards.h>
 #include <asm/irq.h>
 #include <asm/mmu_context.h>
-#include <asm/smp.h>
 #include <asm/mipsregs.h>
 #include <asm/cacheflush.h>
 #include <asm/time.h>
@@ -66,7 +65,7 @@ asiduse smtc_live_asid[MAX_SMTC_TLBS][MAX_SMTC_ASIDS];
 static atomic_t ipi_timer_latch[NR_CPUS];
 
 /*
- * Number of InterProcessor Interupt (IPI) message buffers to allocate
+ * Number of InterProcessor Interrupt (IPI) message buffers to allocate
  */
 
 #define IPIBUF_PER_CPU 4
@@ -88,11 +87,19 @@ unsigned int smtc_status = 0;
 
 /* Boot command line configuration overrides */
 
+static int vpe0limit;
 static int ipibuffers = 0;
 static int nostlb = 0;
 static int asidmask = 0;
 unsigned long smtc_asid_mask = 0xff;
 
+static int __init vpe0tcs(char *str)
+{
+       get_option(&str, &vpe0limit);
+
+       return 1;
+}
+
 static int __init ipibufs(char *str)
 {
        get_option(&str, &ipibuffers);
@@ -125,6 +132,7 @@ static int __init asidmask_set(char *str)
        return 1;
 }
 
+__setup("vpe0tcs=", vpe0tcs);
 __setup("ipibufs=", ipibufs);
 __setup("nostlb", stlb_disable);
 __setup("asidmask=", asidmask_set);
@@ -166,14 +174,6 @@ static int clock_hang_reported[NR_CPUS];
 
 #endif /* CONFIG_SMTC_IDLE_HOOK_DEBUG */
 
-/* Initialize shared TLB - the should probably migrate to smtc_setup_cpus() */
-
-void __init sanitize_tlb_entries(void)
-{
-       printk("Deprecated sanitize_tlb_entries() invoked\n");
-}
-
-
 /*
  * Configure shared TLB - VPC configuration bit must be set by caller
  */
@@ -331,7 +331,8 @@ static void smtc_tc_setup(int vpe, int tc, int cpu)
        /* In general, all TCs should have the same cpu_data indications */
        memcpy(&cpu_data[cpu], &cpu_data[0], sizeof(struct cpuinfo_mips));
        /* For 34Kf, start with TC/CPU 0 as sole owner of single FPU context */
-       if (cpu_data[0].cputype == CPU_34K)
+       if (cpu_data[0].cputype == CPU_34K ||
+           cpu_data[0].cputype == CPU_1004K)
                cpu_data[cpu].options &= ~MIPS_CPU_FPU;
        cpu_data[cpu].vpe_id = vpe;
        cpu_data[cpu].tc_id = tc;
@@ -340,7 +341,7 @@ static void smtc_tc_setup(int vpe, int tc, int cpu)
 
 void mipsmt_prepare_cpus(void)
 {
-       int i, vpe, tc, ntc, nvpe, tcpervpe, slop, cpu;
+       int i, vpe, tc, ntc, nvpe, tcpervpe[NR_CPUS], slop, cpu;
        unsigned long flags;
        unsigned long val;
        int nipi;
@@ -401,8 +402,39 @@ void mipsmt_prepare_cpus(void)
                ntc = NR_CPUS;
        if (tclimit > 0 && ntc > tclimit)
                ntc = tclimit;
-       tcpervpe = ntc / nvpe;
-       slop = ntc % nvpe;      /* Residual TCs, < NVPE */
+       slop = ntc % nvpe;
+       for (i = 0; i < nvpe; i++) {
+               tcpervpe[i] = ntc / nvpe;
+               if (slop) {
+                       if((slop - i) > 0) tcpervpe[i]++;
+               }
+       }
+       /* Handle command line override for VPE0 */
+       if (vpe0limit > ntc) vpe0limit = ntc;
+       if (vpe0limit > 0) {
+               int slopslop;
+               if (vpe0limit < tcpervpe[0]) {
+                   /* Reducing TC count - distribute to others */
+                   slop = tcpervpe[0] - vpe0limit;
+                   slopslop = slop % (nvpe - 1);
+                   tcpervpe[0] = vpe0limit;
+                   for (i = 1; i < nvpe; i++) {
+                       tcpervpe[i] += slop / (nvpe - 1);
+                       if(slopslop && ((slopslop - (i - 1) > 0)))
+                               tcpervpe[i]++;
+                   }
+               } else if (vpe0limit > tcpervpe[0]) {
+                   /* Increasing TC count - steal from others */
+                   slop = vpe0limit - tcpervpe[0];
+                   slopslop = slop % (nvpe - 1);
+                   tcpervpe[0] = vpe0limit;
+                   for (i = 1; i < nvpe; i++) {
+                       tcpervpe[i] -= slop / (nvpe - 1);
+                       if(slopslop && ((slopslop - (i - 1) > 0)))
+                               tcpervpe[i]--;
+                   }
+               }
+       }
 
        /* Set up shared TLB */
        smtc_configure_tlb();
@@ -416,7 +448,7 @@ void mipsmt_prepare_cpus(void)
                if (vpe != 0)
                        printk(", ");
                printk("VPE %d: TC", vpe);
-               for (i = 0; i < tcpervpe; i++) {
+               for (i = 0; i < tcpervpe[vpe]; i++) {
                        /*
                         * TC 0 is bound to VPE 0 at reset,
                         * and is presumably executing this
@@ -429,15 +461,6 @@ void mipsmt_prepare_cpus(void)
                        printk(" %d", tc);
                        tc++;
                }
-               if (slop) {
-                       if (tc != 0) {
-                               smtc_tc_setup(vpe, tc, cpu);
-                               cpu++;
-                       }
-                       printk(" %d", tc);
-                       tc++;
-                       slop--;
-               }
                if (vpe != 0) {
                        /*
                         * Clear any stale software interrupts from VPE's Cause
@@ -750,7 +773,7 @@ void smtc_send_ipi(int cpu, int type, unsigned int action)
        if (cpu_data[cpu].vpe_id != cpu_data[smp_processor_id()].vpe_id) {
                if (type == SMTC_CLOCK_TICK)
                        atomic_inc(&ipi_timer_latch[cpu]);
-               /* If not on same VPE, enqueue and send cross-VPE interupt */
+               /* If not on same VPE, enqueue and send cross-VPE interrupt */
                smtc_ipi_nq(&IPIQ[cpu], pipi);
                LOCK_CORE_PRA();
                settc(cpu_data[cpu].tc_id);
@@ -854,7 +877,6 @@ static void ipi_resched_interrupt(void)
        /* Return from interrupt should be enough to cause scheduler check */
 }
 
-
 static void ipi_call_interrupt(void)
 {
        /* Invoke generic function invocation code in smp.c */
@@ -1033,7 +1055,7 @@ static void setup_cross_vpe_interrupts(unsigned int nvpe)
                return;
 
        if (!cpu_has_vint)
-               panic("SMTC Kernel requires Vectored Interupt support");
+               panic("SMTC Kernel requires Vectored Interrupt support");
 
        set_vi_handler(MIPS_CPU_IPI_IRQ, ipi_irq_dispatch);