|
@@ -61,14 +61,15 @@ static int pnv_smp_kick_cpu(int nr)
|
|
|
unsigned long start_here =
|
|
|
__pa(ppc_function_entry(generic_secondary_smp_init));
|
|
|
long rc;
|
|
|
+ uint8_t status;
|
|
|
|
|
|
BUG_ON(nr < 0 || nr >= NR_CPUS);
|
|
|
|
|
|
/*
|
|
|
- * If we already started or OPALv3 is not supported, we just
|
|
|
+ * If we already started or OPAL is not supported, we just
|
|
|
* kick the CPU via the PACA
|
|
|
*/
|
|
|
- if (paca[nr].cpu_start || !firmware_has_feature(FW_FEATURE_OPALv3))
|
|
|
+ if (paca[nr].cpu_start || !firmware_has_feature(FW_FEATURE_OPAL))
|
|
|
goto kick;
|
|
|
|
|
|
/*
|
|
@@ -77,55 +78,42 @@ static int pnv_smp_kick_cpu(int nr)
|
|
|
* first time. OPAL v3 allows us to query OPAL to know if it
|
|
|
* has the CPUs, so we do that
|
|
|
*/
|
|
|
- if (firmware_has_feature(FW_FEATURE_OPALv3)) {
|
|
|
- uint8_t status;
|
|
|
-
|
|
|
- rc = opal_query_cpu_status(pcpu, &status);
|
|
|
- if (rc != OPAL_SUCCESS) {
|
|
|
- pr_warn("OPAL Error %ld querying CPU %d state\n",
|
|
|
- rc, nr);
|
|
|
- return -ENODEV;
|
|
|
- }
|
|
|
+ rc = opal_query_cpu_status(pcpu, &status);
|
|
|
+ if (rc != OPAL_SUCCESS) {
|
|
|
+ pr_warn("OPAL Error %ld querying CPU %d state\n", rc, nr);
|
|
|
+ return -ENODEV;
|
|
|
+ }
|
|
|
|
|
|
- /*
|
|
|
- * Already started, just kick it, probably coming from
|
|
|
- * kexec and spinning
|
|
|
- */
|
|
|
- if (status == OPAL_THREAD_STARTED)
|
|
|
- goto kick;
|
|
|
+ /*
|
|
|
+ * Already started, just kick it, probably coming from
|
|
|
+ * kexec and spinning
|
|
|
+ */
|
|
|
+ if (status == OPAL_THREAD_STARTED)
|
|
|
+ goto kick;
|
|
|
|
|
|
- /*
|
|
|
- * Available/inactive, let's kick it
|
|
|
- */
|
|
|
- if (status == OPAL_THREAD_INACTIVE) {
|
|
|
- pr_devel("OPAL: Starting CPU %d (HW 0x%x)...\n",
|
|
|
- nr, pcpu);
|
|
|
- rc = opal_start_cpu(pcpu, start_here);
|
|
|
- if (rc != OPAL_SUCCESS) {
|
|
|
- pr_warn("OPAL Error %ld starting CPU %d\n",
|
|
|
- rc, nr);
|
|
|
- return -ENODEV;
|
|
|
- }
|
|
|
- } else {
|
|
|
- /*
|
|
|
- * An unavailable CPU (or any other unknown status)
|
|
|
- * shouldn't be started. It should also
|
|
|
- * not be in the possible map but currently it can
|
|
|
- * happen
|
|
|
- */
|
|
|
- pr_devel("OPAL: CPU %d (HW 0x%x) is unavailable"
|
|
|
- " (status %d)...\n", nr, pcpu, status);
|
|
|
+ /*
|
|
|
+ * Available/inactive, let's kick it
|
|
|
+ */
|
|
|
+ if (status == OPAL_THREAD_INACTIVE) {
|
|
|
+ pr_devel("OPAL: Starting CPU %d (HW 0x%x)...\n", nr, pcpu);
|
|
|
+ rc = opal_start_cpu(pcpu, start_here);
|
|
|
+ if (rc != OPAL_SUCCESS) {
|
|
|
+ pr_warn("OPAL Error %ld starting CPU %d\n", rc, nr);
|
|
|
return -ENODEV;
|
|
|
}
|
|
|
} else {
|
|
|
/*
|
|
|
- * On OPAL v2, we just kick it and hope for the best,
|
|
|
- * we must not test the error from opal_start_cpu() or
|
|
|
- * we would fail to get CPUs from kexec.
|
|
|
+ * An unavailable CPU (or any other unknown status)
|
|
|
+ * shouldn't be started. It should also
|
|
|
+ * not be in the possible map but currently it can
|
|
|
+ * happen
|
|
|
*/
|
|
|
- opal_start_cpu(pcpu, start_here);
|
|
|
+ pr_devel("OPAL: CPU %d (HW 0x%x) is unavailable"
|
|
|
+ " (status %d)...\n", nr, pcpu, status);
|
|
|
+ return -ENODEV;
|
|
|
}
|
|
|
- kick:
|
|
|
+
|
|
|
+kick:
|
|
|
return smp_generic_kick_cpu(nr);
|
|
|
}
|
|
|
|