MIPS: Netlogic: Move from u32 cpumask to cpumask_t
[linux-2.6-block.git] / arch / mips / netlogic / xlp / wakeup.c
index 44d923ff3846fff1ac87482fbc68cdf516041ed3..88ce38d096f0e2ef6a71e2365b66acc5c775a9af 100644 (file)
 #include <asm/netlogic/xlp-hal/xlp.h>
 #include <asm/netlogic/xlp-hal/sys.h>
 
-static void xlp_enable_secondary_cores(void)
+static int xlp_wakeup_core(uint64_t sysbase, int core)
 {
-       uint32_t core, value, coremask, syscoremask;
+       uint32_t coremask, value;
        int count;
 
-       /* read cores in reset from SYS block */
-       syscoremask = nlm_read_sys_reg(nlm_sys_base, SYS_CPU_RESET);
+       coremask = (1 << core);
 
-       /* update user specified */
-       nlm_coremask = nlm_coremask & (syscoremask | 1);
+       /* Enable CPU clock */
+       value = nlm_read_sys_reg(sysbase, SYS_CORE_DFS_DIS_CTRL);
+       value &= ~coremask;
+       nlm_write_sys_reg(sysbase, SYS_CORE_DFS_DIS_CTRL, value);
 
-       for (core = 1; core < 8; core++) {
-               coremask = 1 << core;
-               if ((nlm_coremask & coremask) == 0)
-                       continue;
+       /* Remove CPU Reset */
+       value = nlm_read_sys_reg(sysbase, SYS_CPU_RESET);
+       value &= ~coremask;
+       nlm_write_sys_reg(sysbase, SYS_CPU_RESET, value);
 
-               /* Enable CPU clock */
-               value = nlm_read_sys_reg(nlm_sys_base, SYS_CORE_DFS_DIS_CTRL);
-               value &= ~coremask;
-               nlm_write_sys_reg(nlm_sys_base, SYS_CORE_DFS_DIS_CTRL, value);
+       /* Poll for CPU to mark itself coherent */
+       count = 100000;
+       do {
+               value = nlm_read_sys_reg(sysbase, SYS_CPU_NONCOHERENT_MODE);
+       } while ((value & coremask) != 0 && --count > 0);
 
-               /* Remove CPU Reset */
-               value = nlm_read_sys_reg(nlm_sys_base, SYS_CPU_RESET);
-               value &= ~coremask;
-               nlm_write_sys_reg(nlm_sys_base, SYS_CPU_RESET, value);
+       return count != 0;
+}
+
+static void xlp_enable_secondary_cores(const cpumask_t *wakeup_mask)
+{
+       uint64_t syspcibase, sysbase;
+       uint32_t syscoremask;
+       int core, n;
+
+       for (n = 0; n < 4; n++) {
+               syspcibase = nlm_get_sys_pcibase(n);
+               if (nlm_read_reg(syspcibase, 0) == 0xffffffff)
+                       break;
+
+               /* read cores in reset from SYS and account for boot cpu */
+               sysbase = nlm_get_sys_regbase(n);
+               syscoremask = nlm_read_sys_reg(sysbase, SYS_CPU_RESET);
+               if (n == 0)
+                       syscoremask |= 1;
+
+               for (core = 0; core < 8; core++) {
+                       /* see if the core exists */
+                       if ((syscoremask & (1 << core)) == 0)
+                               continue;
 
-               /* Poll for CPU to mark itself coherent */
-               count = 100000;
-               do {
-                       value = nlm_read_sys_reg(nlm_sys_base,
-                           SYS_CPU_NONCOHERENT_MODE);
-               } while ((value & coremask) != 0 && count-- > 0);
+                       /* see if at least the first thread is enabled */
+                       if (!cpumask_test_cpu((n * 8 + core) * 4, wakeup_mask))
+                               continue;
 
-               if (count == 0)
-                       pr_err("Failed to enable core %d\n", core);
+                       /* wake up the core */
+                       if (!xlp_wakeup_core(sysbase, core))
+                               pr_err("Failed to enable core %d\n", core);
+               }
        }
 }
 
-void xlp_wakeup_secondary_cpus(void)
+void xlp_wakeup_secondary_cpus()
 {
        /*
         * In case of u-boot, the secondaries are in reset
@@ -98,5 +119,5 @@ void xlp_wakeup_secondary_cpus(void)
        xlp_boot_core0_siblings();
 
        /* now get other cores out of reset */
-       xlp_enable_secondary_cores();
+       xlp_enable_secondary_cores(&nlm_cpumask);
 }