diff options
Diffstat (limited to 'arch/powerpc/platforms/powernv/setup.c')
-rw-r--r-- | arch/powerpc/platforms/powernv/setup.c | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/arch/powerpc/platforms/powernv/setup.c b/arch/powerpc/platforms/powernv/setup.c index d4459bf..19884b2 100644 --- a/arch/powerpc/platforms/powernv/setup.c +++ b/arch/powerpc/platforms/powernv/setup.c @@ -23,6 +23,7 @@ #include <linux/irq.h> #include <linux/seq_file.h> #include <linux/of.h> +#include <linux/of_fdt.h> #include <linux/interrupt.h> #include <linux/bug.h> @@ -31,6 +32,7 @@ #include <asm/xics.h> #include <asm/rtas.h> #include <asm/opal.h> +#include <asm/kexec.h> #include "powernv.h" @@ -54,6 +56,12 @@ static void __init pnv_setup_arch(void) static void __init pnv_init_early(void) { + /* + * Initialize the LPC bus now so that legacy serial + * ports can be found on it + */ + opal_lpc_init(); + #ifdef CONFIG_HVC_OPAL if (firmware_has_feature(FW_FEATURE_OPAL)) hvc_opal_init_early(); @@ -93,6 +101,8 @@ static void __noreturn pnv_restart(char *cmd) { long rc = OPAL_BUSY; + opal_notifier_disable(); + while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) { rc = opal_cec_reboot(); if (rc == OPAL_BUSY_EVENT) @@ -108,6 +118,8 @@ static void __noreturn pnv_power_off(void) { long rc = OPAL_BUSY; + opal_notifier_disable(); + while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) { rc = opal_cec_power_down(0); if (rc == OPAL_BUSY_EVENT) @@ -143,6 +155,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 */ |