powerpc/powernv: Return secondary CPUs to firmware on kexec
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>
Wed, 21 Aug 2013 03:03:20 +0000 (13:03 +1000)
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>
Tue, 27 Aug 2013 07:43:50 +0000 (17:43 +1000)
With OPAL v3 we can return secondary CPUs to firmware on kexec. This
allows firmware to do various cleanups making things generally more
reliable, and will enable the "new" kernel to call OPAL to perform
some reconfiguration tasks early on that can only be done while
all the CPUs are in firmware.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
arch/powerpc/include/asm/opal.h
arch/powerpc/platforms/powernv/opal-wrappers.S
arch/powerpc/platforms/powernv/setup.c

index 48ad6780c6d980d3fc5ac4921c0f3fdd12291e80..c5cd72833d6e7f29daba00655296750b0c560b16 100644 (file)
@@ -128,6 +128,7 @@ extern int opal_enter_rtas(struct rtas_args *args,
 #define OPAL_XSCOM_WRITE                       66
 #define OPAL_LPC_READ                          67
 #define OPAL_LPC_WRITE                         68
+#define OPAL_RETURN_CPU                                69
 
 #ifndef __ASSEMBLY__
 
@@ -646,6 +647,7 @@ int64_t opal_set_system_attention_led(uint8_t led_action);
 int64_t opal_pci_next_error(uint64_t phb_id, uint64_t *first_frozen_pe,
                            uint16_t *pci_error_type, uint16_t *severity);
 int64_t opal_pci_poll(uint64_t phb_id);
+int64_t opal_return_cpu(void);
 
 int64_t opal_xscom_read(uint32_t gcid, uint32_t pcb_addr, uint64_t *val);
 int64_t opal_xscom_write(uint32_t gcid, uint32_t pcb_addr, uint64_t val);
index 42c06fba3994ad817984d58369832db032451026..8f3844535fbb2e4167ced361831e6c2aeab9a190 100644 (file)
@@ -115,3 +115,4 @@ OPAL_CALL(opal_xscom_read,                  OPAL_XSCOM_READ);
 OPAL_CALL(opal_xscom_write,                    OPAL_XSCOM_WRITE);
 OPAL_CALL(opal_lpc_read,                       OPAL_LPC_READ);
 OPAL_CALL(opal_lpc_write,                      OPAL_LPC_WRITE);
+OPAL_CALL(opal_return_cpu,                     OPAL_RETURN_CPU);
index 4ddb339700b9453b1c02b793a0d03b302984c570..e239dcfa224c2727bd6411aada2eb65120ad4a8a 100644 (file)
@@ -31,6 +31,7 @@
 #include <asm/xics.h>
 #include <asm/rtas.h>
 #include <asm/opal.h>
+#include <asm/kexec.h>
 
 #include "powernv.h"
 
@@ -153,6 +154,16 @@ static void pnv_shutdown(void)
 static void pnv_kexec_cpu_down(int crash_shutdown, int secondary)
 {
        xics_kexec_teardown_cpu(secondary);
+
+       /* Return secondary CPUs to firmware on OPAL v3 */
+       if (firmware_has_feature(FW_FEATURE_OPALv3) && secondary) {
+               mb();
+               get_paca()->kexec_state = KEXEC_STATE_REAL_MODE;
+               mb();
+
+               /* Return the CPU to OPAL */
+               opal_return_cpu();
+       }
 }
 #endif /* CONFIG_KEXEC */