char rtas_data_buf[RTAS_DATA_BUF_SIZE] __cacheline_aligned;
unsigned long rtas_rmo_buf;
+/*
+ * If non-NULL, this gets called when the kernel terminates.
+ * This is done like this so rtas_flash can be a module.
+ */
+void (*rtas_flash_term_hook)(int);
+EXPORT_SYMBOL(rtas_flash_term_hook);
+
/*
* call_rtas_display_status and call_rtas_display_status_delay
* are designed only for very early low-level debugging, which
spin_unlock(&progress_lock);
}
+EXPORT_SYMBOL(rtas_progress); /* needed by rtas_flash module */
int rtas_token(const char *service)
{
void rtas_restart(char *cmd)
{
+ if (rtas_flash_term_hook)
+ rtas_flash_term_hook(SYS_RESTART);
printk("RTAS system-reboot returned %d\n",
rtas_call(rtas_token("system-reboot"), 0, 1, NULL));
for (;;);
void rtas_power_off(void)
{
+ if (rtas_flash_term_hook)
+ rtas_flash_term_hook(SYS_POWER_OFF);
/* allow power on only with power button press */
printk("RTAS power-off returned %d\n",
rtas_call(rtas_token("power-off"), 2, 1, NULL, -1, -1));
void rtas_halt(void)
{
- rtas_power_off();
+ if (rtas_flash_term_hook)
+ rtas_flash_term_hook(SYS_HALT);
+ /* allow power on only with power button press */
+ printk("RTAS power-off returned %d\n",
+ rtas_call(rtas_token("power-off"), 2, 1, NULL, -1, -1));
+ for (;;);
}
/* Must be in the RMO region, so we place it here */
return 0;
}
-#ifdef CONFIG_SMP
/* This version can't take the spinlock, because it never returns */
struct rtas_args rtas_stop_self_args = {
panic("Alas, I survived.\n");
}
-#endif
/*
* Call early during boot, before mem init or bootmem, to retreive the RTAS