diff options
Diffstat (limited to 'arch/mips/netlogic/xlp/wakeup.c')
-rw-r--r-- | arch/mips/netlogic/xlp/wakeup.c | 35 |
1 files changed, 25 insertions, 10 deletions
diff --git a/arch/mips/netlogic/xlp/wakeup.c b/arch/mips/netlogic/xlp/wakeup.c index cb9010642ac3..abb3e08cc052 100644 --- a/arch/mips/netlogic/xlp/wakeup.c +++ b/arch/mips/netlogic/xlp/wakeup.c | |||
@@ -51,7 +51,7 @@ | |||
51 | #include <asm/netlogic/xlp-hal/xlp.h> | 51 | #include <asm/netlogic/xlp-hal/xlp.h> |
52 | #include <asm/netlogic/xlp-hal/sys.h> | 52 | #include <asm/netlogic/xlp-hal/sys.h> |
53 | 53 | ||
54 | static int xlp_wakeup_core(uint64_t sysbase, int core) | 54 | static int xlp_wakeup_core(uint64_t sysbase, int node, int core) |
55 | { | 55 | { |
56 | uint32_t coremask, value; | 56 | uint32_t coremask, value; |
57 | int count; | 57 | int count; |
@@ -82,36 +82,51 @@ static void xlp_enable_secondary_cores(const cpumask_t *wakeup_mask) | |||
82 | struct nlm_soc_info *nodep; | 82 | struct nlm_soc_info *nodep; |
83 | uint64_t syspcibase; | 83 | uint64_t syspcibase; |
84 | uint32_t syscoremask; | 84 | uint32_t syscoremask; |
85 | int core, n, cpu; | 85 | int core, n, cpu, count, val; |
86 | 86 | ||
87 | for (n = 0; n < NLM_NR_NODES; n++) { | 87 | for (n = 0; n < NLM_NR_NODES; n++) { |
88 | syspcibase = nlm_get_sys_pcibase(n); | 88 | syspcibase = nlm_get_sys_pcibase(n); |
89 | if (nlm_read_reg(syspcibase, 0) == 0xffffffff) | 89 | if (nlm_read_reg(syspcibase, 0) == 0xffffffff) |
90 | break; | 90 | break; |
91 | 91 | ||
92 | /* read cores in reset from SYS and account for boot cpu */ | 92 | /* read cores in reset from SYS */ |
93 | nlm_node_init(n); | 93 | if (n != 0) |
94 | nlm_node_init(n); | ||
94 | nodep = nlm_get_node(n); | 95 | nodep = nlm_get_node(n); |
95 | syscoremask = nlm_read_sys_reg(nodep->sysbase, SYS_CPU_RESET); | 96 | syscoremask = nlm_read_sys_reg(nodep->sysbase, SYS_CPU_RESET); |
96 | if (n == 0) | 97 | /* The boot cpu */ |
98 | if (n == 0) { | ||
97 | syscoremask |= 1; | 99 | syscoremask |= 1; |
100 | nodep->coremask = 1; | ||
101 | } | ||
98 | 102 | ||
99 | for (core = 0; core < NLM_CORES_PER_NODE; core++) { | 103 | for (core = 0; core < NLM_CORES_PER_NODE; core++) { |
104 | /* we will be on node 0 core 0 */ | ||
105 | if (n == 0 && core == 0) | ||
106 | continue; | ||
107 | |||
100 | /* see if the core exists */ | 108 | /* see if the core exists */ |
101 | if ((syscoremask & (1 << core)) == 0) | 109 | if ((syscoremask & (1 << core)) == 0) |
102 | continue; | 110 | continue; |
103 | 111 | ||
104 | /* see if at least the first thread is enabled */ | 112 | /* see if at least the first hw thread is enabled */ |
105 | cpu = (n * NLM_CORES_PER_NODE + core) | 113 | cpu = (n * NLM_CORES_PER_NODE + core) |
106 | * NLM_THREADS_PER_CORE; | 114 | * NLM_THREADS_PER_CORE; |
107 | if (!cpumask_test_cpu(cpu, wakeup_mask)) | 115 | if (!cpumask_test_cpu(cpu, wakeup_mask)) |
108 | continue; | 116 | continue; |
109 | 117 | ||
110 | /* wake up the core */ | 118 | /* wake up the core */ |
111 | if (xlp_wakeup_core(nodep->sysbase, core)) | 119 | if (!xlp_wakeup_core(nodep->sysbase, n, core)) |
112 | nodep->coremask |= 1u << core; | 120 | continue; |
113 | else | 121 | |
114 | pr_err("Failed to enable core %d\n", core); | 122 | /* core is up */ |
123 | nodep->coremask |= 1u << core; | ||
124 | |||
125 | /* spin until the first hw thread sets its ready */ | ||
126 | count = 0x20000000; | ||
127 | do { | ||
128 | val = *(volatile int *)&nlm_cpu_ready[cpu]; | ||
129 | } while (val == 0 && --count > 0); | ||
115 | } | 130 | } |
116 | } | 131 | } |
117 | } | 132 | } |