diff options
-rw-r--r-- | arch/powerpc/include/asm/opal.h | 2 | ||||
-rw-r--r-- | arch/powerpc/platforms/powernv/opal-wrappers.S | 1 | ||||
-rw-r--r-- | arch/powerpc/platforms/powernv/opal.c | 16 | ||||
-rw-r--r-- | arch/powerpc/platforms/powernv/setup.c | 6 |
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 | ||
829 | int64_t opal_get_msg(uint64_t buffer, size_t size); | 830 | int64_t opal_get_msg(uint64_t buffer, size_t size); |
830 | int64_t opal_check_completion(uint64_t buffer, size_t size, uint64_t token); | 831 | int64_t opal_check_completion(uint64_t buffer, size_t size, uint64_t token); |
832 | int64_t opal_sync_host_reboot(void); | ||
831 | 833 | ||
832 | /* Internal functions */ | 834 | /* Internal functions */ |
833 | extern int early_init_dt_scan_opal(unsigned long node, const char *uname, int depth, void *data); | 835 | extern 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); | |||
128 | OPAL_CALL(opal_update_flash, OPAL_FLASH_UPDATE); | 128 | OPAL_CALL(opal_update_flash, OPAL_FLASH_UPDATE); |
129 | OPAL_CALL(opal_get_msg, OPAL_GET_MSG); | 129 | OPAL_CALL(opal_get_msg, OPAL_GET_MSG); |
130 | OPAL_CALL(opal_check_completion, OPAL_CHECK_ASYNC_COMPLETION); | 130 | OPAL_CALL(opal_check_completion, OPAL_CHECK_ASYNC_COMPLETION); |
131 | OPAL_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); | |||
482 | void opal_shutdown(void) | 483 | void 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 | } |