aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/include/asm/opal.h2
-rw-r--r--arch/powerpc/platforms/powernv/opal-wrappers.S1
-rw-r--r--arch/powerpc/platforms/powernv/opal.c16
-rw-r--r--arch/powerpc/platforms/powernv/setup.c6
4 files changed, 23 insertions, 2 deletions
diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h
index 9a87b4401a41..40157e2ca691 100644
--- a/arch/powerpc/include/asm/opal.h
+++ b/arch/powerpc/include/asm/opal.h
@@ -156,6 +156,7 @@ extern int opal_enter_rtas(struct rtas_args *args,
156#define OPAL_FLASH_UPDATE 78 156#define OPAL_FLASH_UPDATE 78
157#define OPAL_GET_MSG 85 157#define OPAL_GET_MSG 85
158#define OPAL_CHECK_ASYNC_COMPLETION 86 158#define OPAL_CHECK_ASYNC_COMPLETION 86
159#define OPAL_SYNC_HOST_REBOOT 87
159 160
160#ifndef __ASSEMBLY__ 161#ifndef __ASSEMBLY__
161 162
@@ -828,6 +829,7 @@ int64_t opal_update_flash(uint64_t blk_list);
828 829
829int64_t opal_get_msg(uint64_t buffer, size_t size); 830int64_t opal_get_msg(uint64_t buffer, size_t size);
830int64_t opal_check_completion(uint64_t buffer, size_t size, uint64_t token); 831int64_t opal_check_completion(uint64_t buffer, size_t size, uint64_t token);
832int64_t opal_sync_host_reboot(void);
831 833
832/* Internal functions */ 834/* Internal functions */
833extern int early_init_dt_scan_opal(unsigned long node, const char *uname, int depth, void *data); 835extern int early_init_dt_scan_opal(unsigned long node, const char *uname, int depth, void *data);
diff --git a/arch/powerpc/platforms/powernv/opal-wrappers.S b/arch/powerpc/platforms/powernv/opal-wrappers.S
index 719aa5c325c6..3e8829c40fbb 100644
--- a/arch/powerpc/platforms/powernv/opal-wrappers.S
+++ b/arch/powerpc/platforms/powernv/opal-wrappers.S
@@ -128,3 +128,4 @@ OPAL_CALL(opal_manage_flash, OPAL_FLASH_MANAGE);
128OPAL_CALL(opal_update_flash, OPAL_FLASH_UPDATE); 128OPAL_CALL(opal_update_flash, OPAL_FLASH_UPDATE);
129OPAL_CALL(opal_get_msg, OPAL_GET_MSG); 129OPAL_CALL(opal_get_msg, OPAL_GET_MSG);
130OPAL_CALL(opal_check_completion, OPAL_CHECK_ASYNC_COMPLETION); 130OPAL_CALL(opal_check_completion, OPAL_CHECK_ASYNC_COMPLETION);
131OPAL_CALL(opal_sync_host_reboot, OPAL_SYNC_HOST_REBOOT);
diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c
index 7a184a0ff183..65499adaecff 100644
--- a/arch/powerpc/platforms/powernv/opal.c
+++ b/arch/powerpc/platforms/powernv/opal.c
@@ -20,6 +20,7 @@
20#include <linux/slab.h> 20#include <linux/slab.h>
21#include <linux/sched.h> 21#include <linux/sched.h>
22#include <linux/kobject.h> 22#include <linux/kobject.h>
23#include <linux/delay.h>
23#include <asm/opal.h> 24#include <asm/opal.h>
24#include <asm/firmware.h> 25#include <asm/firmware.h>
25#include <asm/mce.h> 26#include <asm/mce.h>
@@ -482,10 +483,25 @@ subsys_initcall(opal_init);
482void opal_shutdown(void) 483void opal_shutdown(void)
483{ 484{
484 unsigned int i; 485 unsigned int i;
486 long rc = OPAL_BUSY;
485 487
488 /* First free interrupts, which will also mask them */
486 for (i = 0; i < opal_irq_count; i++) { 489 for (i = 0; i < opal_irq_count; i++) {
487 if (opal_irqs[i]) 490 if (opal_irqs[i])
488 free_irq(opal_irqs[i], NULL); 491 free_irq(opal_irqs[i], NULL);
489 opal_irqs[i] = 0; 492 opal_irqs[i] = 0;
490 } 493 }
494
495 /*
496 * Then sync with OPAL which ensure anything that can
497 * potentially write to our memory has completed such
498 * as an ongoing dump retrieval
499 */
500 while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) {
501 rc = opal_sync_host_reboot();
502 if (rc == OPAL_BUSY)
503 opal_poll_events(NULL);
504 else
505 mdelay(10);
506 }
491} 507}
diff --git a/arch/powerpc/platforms/powernv/setup.c b/arch/powerpc/platforms/powernv/setup.c
index 19884b2a51b4..a932feb2901c 100644
--- a/arch/powerpc/platforms/powernv/setup.c
+++ b/arch/powerpc/platforms/powernv/setup.c
@@ -145,8 +145,10 @@ static void pnv_shutdown(void)
145 /* Let the PCI code clear up IODA tables */ 145 /* Let the PCI code clear up IODA tables */
146 pnv_pci_shutdown(); 146 pnv_pci_shutdown();
147 147
148 /* And unregister all OPAL interrupts so they don't fire 148 /*
149 * up while we kexec 149 * Stop OPAL activity: Unregister all OPAL interrupts so they
150 * don't fire up while we kexec and make sure all potentially
151 * DMA'ing ops are complete (such as dump retrieval).
150 */ 152 */
151 opal_shutdown(); 153 opal_shutdown();
152} 154}