diff options
-rw-r--r-- | arch/powerpc/platforms/pseries/setup.c | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index 5d97553e5c22..ca55882465d6 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include <linux/root_dev.h> | 41 | #include <linux/root_dev.h> |
42 | #include <linux/cpuidle.h> | 42 | #include <linux/cpuidle.h> |
43 | #include <linux/of.h> | 43 | #include <linux/of.h> |
44 | #include <linux/kexec.h> | ||
44 | 45 | ||
45 | #include <asm/mmu.h> | 46 | #include <asm/mmu.h> |
46 | #include <asm/processor.h> | 47 | #include <asm/processor.h> |
@@ -397,6 +398,35 @@ static int __init pSeries_enable_reloc_on_exc(void) | |||
397 | } | 398 | } |
398 | } | 399 | } |
399 | 400 | ||
401 | #ifdef CONFIG_KEXEC | ||
402 | static long pSeries_disable_reloc_on_exc(void) | ||
403 | { | ||
404 | long rc; | ||
405 | |||
406 | while (1) { | ||
407 | rc = disable_reloc_on_exceptions(); | ||
408 | if (!H_IS_LONG_BUSY(rc)) | ||
409 | return rc; | ||
410 | mdelay(get_longbusy_msecs(rc)); | ||
411 | } | ||
412 | } | ||
413 | |||
414 | static void pSeries_machine_kexec(struct kimage *image) | ||
415 | { | ||
416 | long rc; | ||
417 | |||
418 | if (firmware_has_feature(FW_FEATURE_SET_MODE) && | ||
419 | (image->type != KEXEC_TYPE_CRASH)) { | ||
420 | rc = pSeries_disable_reloc_on_exc(); | ||
421 | if (rc != H_SUCCESS) | ||
422 | pr_warning("Warning: Failed to disable relocation on " | ||
423 | "exceptions: %ld\n", rc); | ||
424 | } | ||
425 | |||
426 | default_machine_kexec(image); | ||
427 | } | ||
428 | #endif | ||
429 | |||
400 | static void __init pSeries_setup_arch(void) | 430 | static void __init pSeries_setup_arch(void) |
401 | { | 431 | { |
402 | panic_timeout = 10; | 432 | panic_timeout = 10; |
@@ -697,4 +727,7 @@ define_machine(pseries) { | |||
697 | .progress = rtas_progress, | 727 | .progress = rtas_progress, |
698 | .system_reset_exception = pSeries_system_reset_exception, | 728 | .system_reset_exception = pSeries_system_reset_exception, |
699 | .machine_check_exception = pSeries_machine_check_exception, | 729 | .machine_check_exception = pSeries_machine_check_exception, |
730 | #ifdef CONFIG_KEXEC | ||
731 | .machine_kexec = pSeries_machine_kexec, | ||
732 | #endif | ||
700 | }; | 733 | }; |