aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/powernv/opal-flash.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/platforms/powernv/opal-flash.c')
-rw-r--r--arch/powerpc/platforms/powernv/opal-flash.c50
1 files changed, 44 insertions, 6 deletions
diff --git a/arch/powerpc/platforms/powernv/opal-flash.c b/arch/powerpc/platforms/powernv/opal-flash.c
index dc487ff04704..5c21d9c07f45 100644
--- a/arch/powerpc/platforms/powernv/opal-flash.c
+++ b/arch/powerpc/platforms/powernv/opal-flash.c
@@ -20,6 +20,7 @@
20#include <linux/mm.h> 20#include <linux/mm.h>
21#include <linux/vmalloc.h> 21#include <linux/vmalloc.h>
22#include <linux/pagemap.h> 22#include <linux/pagemap.h>
23#include <linux/delay.h>
23 24
24#include <asm/opal.h> 25#include <asm/opal.h>
25 26
@@ -130,7 +131,8 @@ static inline void opal_flash_validate(void)
130{ 131{
131 long ret; 132 long ret;
132 void *buf = validate_flash_data.buf; 133 void *buf = validate_flash_data.buf;
133 __be32 size, result; 134 __be32 size = cpu_to_be32(validate_flash_data.buf_size);
135 __be32 result;
134 136
135 ret = opal_validate_flash(__pa(buf), &size, &result); 137 ret = opal_validate_flash(__pa(buf), &size, &result);
136 138
@@ -290,11 +292,6 @@ static int opal_flash_update(int op)
290 /* First entry address */ 292 /* First entry address */
291 addr = __pa(list); 293 addr = __pa(list);
292 294
293 pr_alert("FLASH: Image is %u bytes\n", image_data.size);
294 pr_alert("FLASH: Image update requested\n");
295 pr_alert("FLASH: Image will be updated during system reboot\n");
296 pr_alert("FLASH: This will take several minutes. Do not power off!\n");
297
298flash: 295flash:
299 rc = opal_update_flash(addr); 296 rc = opal_update_flash(addr);
300 297
@@ -302,6 +299,47 @@ invalid_img:
302 return rc; 299 return rc;
303} 300}
304 301
302/* Return CPUs to OPAL before starting FW update */
303static void flash_return_cpu(void *info)
304{
305 int cpu = smp_processor_id();
306
307 if (!cpu_online(cpu))
308 return;
309
310 /* Disable IRQ */
311 hard_irq_disable();
312
313 /* Return the CPU to OPAL */
314 opal_return_cpu();
315}
316
317/* This gets called just before system reboots */
318void opal_flash_term_callback(void)
319{
320 struct cpumask mask;
321
322 if (update_flash_data.status != FLASH_IMG_READY)
323 return;
324
325 pr_alert("FLASH: Flashing new firmware\n");
326 pr_alert("FLASH: Image is %u bytes\n", image_data.size);
327 pr_alert("FLASH: Performing flash and reboot/shutdown\n");
328 pr_alert("FLASH: This will take several minutes. Do not power off!\n");
329
330 /* Small delay to help getting the above message out */
331 msleep(500);
332
333 /* Return secondary CPUs to firmware */
334 cpumask_copy(&mask, cpu_online_mask);
335 cpumask_clear_cpu(smp_processor_id(), &mask);
336 if (!cpumask_empty(&mask))
337 smp_call_function_many(&mask,
338 flash_return_cpu, NULL, false);
339 /* Hard disable interrupts */
340 hard_irq_disable();
341}
342
305/* 343/*
306 * Show candidate image status 344 * Show candidate image status
307 */ 345 */