Commit 69bc70b9 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] ppc64: Add RTAS os-term call for panic on pSeries

From: Michael Strosaker <strosake@us.ibm.com>

Add RTAS os-term call for panic on pSeries
parent 15cddddb
...@@ -267,6 +267,7 @@ chrp_init(unsigned long r3, unsigned long r4, unsigned long r5, ...@@ -267,6 +267,7 @@ chrp_init(unsigned long r3, unsigned long r4, unsigned long r5,
ppc_md.restart = rtas_restart; ppc_md.restart = rtas_restart;
ppc_md.power_off = rtas_power_off; ppc_md.power_off = rtas_power_off;
ppc_md.halt = rtas_halt; ppc_md.halt = rtas_halt;
ppc_md.panic = rtas_os_term;
ppc_md.get_boot_time = pSeries_get_boot_time; ppc_md.get_boot_time = pSeries_get_boot_time;
ppc_md.get_rtc_time = pSeries_get_rtc_time; ppc_md.get_rtc_time = pSeries_get_rtc_time;
......
...@@ -448,6 +448,27 @@ rtas_halt(void) ...@@ -448,6 +448,27 @@ rtas_halt(void)
rtas_power_off(); rtas_power_off();
} }
/* Must be in the RMO region, so we place it here */
static char rtas_os_term_buf[2048];
void rtas_os_term(char *str)
{
long status;
snprintf(rtas_os_term_buf, 2048, "OS panic: %s", str);
do {
status = rtas_call(rtas_token("ibm,os-term"), 1, 1, NULL,
__pa(rtas_os_term_buf));
if (status == RTAS_BUSY)
udelay(1);
else if (status != 0)
printk(KERN_EMERG "ibm,os-term call failed %ld\n",
status);
} while (status == RTAS_BUSY);
}
unsigned long rtas_rmo_buf = 0; unsigned long rtas_rmo_buf = 0;
asmlinkage int ppc_rtas(struct rtas_args __user *uargs) asmlinkage int ppc_rtas(struct rtas_args __user *uargs)
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include <linux/tty.h> #include <linux/tty.h>
#include <linux/root_dev.h> #include <linux/root_dev.h>
#include <linux/cpu.h> #include <linux/cpu.h>
#include <linux/notifier.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/prom.h> #include <asm/prom.h>
#include <asm/processor.h> #include <asm/processor.h>
...@@ -94,6 +95,13 @@ unsigned long SYSRQ_KEY; ...@@ -94,6 +95,13 @@ unsigned long SYSRQ_KEY;
struct machdep_calls ppc_md; struct machdep_calls ppc_md;
static int ppc64_panic_event(struct notifier_block *, unsigned long, void *);
static struct notifier_block ppc64_panic_block = {
notifier_call: ppc64_panic_event,
priority: INT_MIN /* may not return; must be done last */
};
/* /*
* Perhaps we can put the pmac screen_info[] here * Perhaps we can put the pmac screen_info[] here
* on pmac as well so we don't need the ifdef's. * on pmac as well so we don't need the ifdef's.
...@@ -319,6 +327,14 @@ EXPORT_SYMBOL(machine_halt); ...@@ -319,6 +327,14 @@ EXPORT_SYMBOL(machine_halt);
unsigned long ppc_proc_freq; unsigned long ppc_proc_freq;
unsigned long ppc_tb_freq; unsigned long ppc_tb_freq;
static int ppc64_panic_event(struct notifier_block *this,
unsigned long event, void *ptr)
{
ppc_md.panic((char *)ptr); /* May not return */
return NOTIFY_DONE;
}
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
DEFINE_PER_CPU(unsigned int, pvr); DEFINE_PER_CPU(unsigned int, pvr);
#endif #endif
...@@ -605,6 +621,9 @@ void __init setup_arch(char **cmdline_p) ...@@ -605,6 +621,9 @@ void __init setup_arch(char **cmdline_p)
/* reboot on panic */ /* reboot on panic */
panic_timeout = 180; panic_timeout = 180;
if (ppc_md.panic)
notifier_chain_register(&panic_notifier_list, &ppc64_panic_block);
init_mm.start_code = PAGE_OFFSET; init_mm.start_code = PAGE_OFFSET;
init_mm.end_code = (unsigned long) _etext; init_mm.end_code = (unsigned long) _etext;
init_mm.end_data = (unsigned long) _edata; init_mm.end_data = (unsigned long) _edata;
......
...@@ -79,6 +79,7 @@ struct machdep_calls { ...@@ -79,6 +79,7 @@ struct machdep_calls {
void (*restart)(char *cmd); void (*restart)(char *cmd);
void (*power_off)(void); void (*power_off)(void);
void (*halt)(void); void (*halt)(void);
void (*panic)(char *str);
int (*set_rtc_time)(struct rtc_time *); int (*set_rtc_time)(struct rtc_time *);
void (*get_rtc_time)(struct rtc_time *); void (*get_rtc_time)(struct rtc_time *);
......
...@@ -175,6 +175,7 @@ extern void call_rtas_display_status(char); ...@@ -175,6 +175,7 @@ extern void call_rtas_display_status(char);
extern void rtas_restart(char *cmd); extern void rtas_restart(char *cmd);
extern void rtas_power_off(void); extern void rtas_power_off(void);
extern void rtas_halt(void); extern void rtas_halt(void);
extern void rtas_os_term(char *str);
extern int rtas_get_sensor(int sensor, int index, int *state); extern int rtas_get_sensor(int sensor, int index, int *state);
extern int rtas_get_power_level(int powerdomain, int *level); extern int rtas_get_power_level(int powerdomain, int *level);
extern int rtas_set_power_level(int powerdomain, int level, int *setlevel); extern int rtas_set_power_level(int powerdomain, int level, int *setlevel);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment