|
@@ -20,6 +20,7 @@
|
|
|
#include <linux/mm.h>
|
|
|
#include <linux/vmalloc.h>
|
|
|
#include <linux/pagemap.h>
|
|
|
+#include <linux/delay.h>
|
|
|
|
|
|
#include <asm/opal.h>
|
|
|
|
|
@@ -290,11 +291,6 @@ static int opal_flash_update(int op)
|
|
|
/* First entry address */
|
|
|
addr = __pa(list);
|
|
|
|
|
|
- pr_alert("FLASH: Image is %u bytes\n", image_data.size);
|
|
|
- pr_alert("FLASH: Image update requested\n");
|
|
|
- pr_alert("FLASH: Image will be updated during system reboot\n");
|
|
|
- pr_alert("FLASH: This will take several minutes. Do not power off!\n");
|
|
|
-
|
|
|
flash:
|
|
|
rc = opal_update_flash(addr);
|
|
|
|
|
@@ -302,6 +298,47 @@ invalid_img:
|
|
|
return rc;
|
|
|
}
|
|
|
|
|
|
+/* Return CPUs to OPAL before starting FW update */
|
|
|
+static void flash_return_cpu(void *info)
|
|
|
+{
|
|
|
+ int cpu = smp_processor_id();
|
|
|
+
|
|
|
+ if (!cpu_online(cpu))
|
|
|
+ return;
|
|
|
+
|
|
|
+ /* Disable IRQ */
|
|
|
+ hard_irq_disable();
|
|
|
+
|
|
|
+ /* Return the CPU to OPAL */
|
|
|
+ opal_return_cpu();
|
|
|
+}
|
|
|
+
|
|
|
+/* This gets called just before system reboots */
|
|
|
+void opal_flash_term_callback(void)
|
|
|
+{
|
|
|
+ struct cpumask mask;
|
|
|
+
|
|
|
+ if (update_flash_data.status != FLASH_IMG_READY)
|
|
|
+ return;
|
|
|
+
|
|
|
+ pr_alert("FLASH: Flashing new firmware\n");
|
|
|
+ pr_alert("FLASH: Image is %u bytes\n", image_data.size);
|
|
|
+ pr_alert("FLASH: Performing flash and reboot/shutdown\n");
|
|
|
+ pr_alert("FLASH: This will take several minutes. Do not power off!\n");
|
|
|
+
|
|
|
+ /* Small delay to help getting the above message out */
|
|
|
+ msleep(500);
|
|
|
+
|
|
|
+ /* Return secondary CPUs to firmware */
|
|
|
+ cpumask_copy(&mask, cpu_online_mask);
|
|
|
+ cpumask_clear_cpu(smp_processor_id(), &mask);
|
|
|
+ if (!cpumask_empty(&mask))
|
|
|
+ smp_call_function_many(&mask,
|
|
|
+ flash_return_cpu, NULL, false);
|
|
|
+ /* Hard disable interrupts */
|
|
|
+ hard_irq_disable();
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* Show candidate image status
|
|
|
*/
|