Index: 2.6-git2/arch/powerpc/kernel/rtas.c =================================================================== --- 2.6-git2.orig/arch/powerpc/kernel/rtas.c 2006-11-29 12:00:26.000000000 -0800 +++ 2.6-git2/arch/powerpc/kernel/rtas.c 2006-11-30 10:56:12.000000000 -0800 @@ -603,11 +603,30 @@ void rtas_power_off(void) { + int rc = 0; + int rtas_poweron_auto_token; + 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)); + + if (rtas_poweron_auto == 0) { + /* allow power on only with power button press */ + printk(KERN_INFO "RTAS power-off returned %d\n", + rtas_call(rtas_token("power-off"), 2, 1, NULL, -1, -1)); + } else { + rtas_poweron_auto_token = rtas_token("ibm,power-off-ups"); + + if (rtas_poweron_auto_token == RTAS_UNKNOWN_SERVICE) { + /* ibm,power-off-ups failed or token does not exist */ + rc = rtas_call(rtas_token("power-off"), 2, 1, NULL, -1, -1); + printk(KERN_EMERG "Power-off called instead %d\n", rc ); + } else { + /* Enable the system to reboot if power comes back on */ + rc = rtas_call(rtas_token("ibm,power-off-ups"), 0, 1, NULL); + printk(KERN_INFO "RTAS ibm,power-off-ups returned %d\n", rc); + } + + } for (;;); } Index: 2.6-git2/arch/powerpc/kernel/rtas-proc.c =================================================================== --- 2.6-git2.orig/arch/powerpc/kernel/rtas-proc.c 2006-11-29 11:51:49.000000000 -0800 +++ 2.6-git2/arch/powerpc/kernel/rtas-proc.c 2006-11-30 11:01:55.000000000 -0800 @@ -122,6 +122,7 @@ static unsigned long rtas_tone_frequency = 1000; static unsigned long rtas_tone_volume = 0; +unsigned long rtas_poweron_auto; /* default and normal state is 0 */ /* ****************STRUCTS******************************************* */ struct individual_sensor { @@ -154,6 +155,9 @@ const char __user *buf, size_t count, loff_t *ppos); static int ppc_rtas_tone_volume_show(struct seq_file *m, void *v); static int ppc_rtas_rmo_buf_show(struct seq_file *m, void *v); +static int ppc_rtas_poweron_auto_show(struct seq_file *m, void *v); +static ssize_t ppc_rtas_poweron_auto_write(struct file *file, + const char __user *buf, size_t count, loff_t *ppos); static int sensors_open(struct inode *inode, struct file *file) { @@ -244,6 +248,18 @@ .release = single_release, }; +static int poweron_auto_open(struct inode *inode, struct file *file) +{ + return single_open(file, ppc_rtas_poweron_auto_show, NULL); +} + +struct file_operations ppc_rtas_poweron_auto_operations = { + .open = poweron_auto_open, + .read = seq_read, + .write = ppc_rtas_poweron_auto_write, + .release = single_release, +}; + static int ppc_rtas_find_all_sensors(void); static void ppc_rtas_process_sensor(struct seq_file *m, struct individual_sensor *s, int state, int error, const char *loc); @@ -293,6 +309,10 @@ if (entry) entry->proc_fops = &ppc_rtas_rmo_buf_ops; + entry = create_proc_entry("ppc64/rtas/poweron_auto", S_IRUGO|S_IWUSR, NULL); + if (entry) + entry->proc_fops = &ppc_rtas_poweron_auto_operations; + return 0; } @@ -805,3 +825,24 @@ seq_printf(m, "%016lx %x\n", rtas_rmo_buf, RTAS_RMOBUF_MAX); return 0; } + +static ssize_t ppc_rtas_poweron_auto_write(struct file *file, + const char __user *buf, size_t count, loff_t *ppos) +{ + unsigned long ups_restart; + int error = parse_number(buf, count, &ups_restart); + if (error) + return error; + + if (ups_restart != 0) + rtas_poweron_auto = 1; + + return count; +} + +static int ppc_rtas_poweron_auto_show(struct seq_file *m, void *v) +{ + seq_printf(m, "%lu\n", rtas_poweron_auto); + return 0; + +} Index: 2.6-git2/include/asm-powerpc/rtas.h =================================================================== --- 2.6-git2.orig/include/asm-powerpc/rtas.h 2006-11-28 14:41:17.000000000 -0800 +++ 2.6-git2/include/asm-powerpc/rtas.h 2006-11-30 10:42:35.000000000 -0800 @@ -228,6 +228,9 @@ /* RMO buffer reserved for user-space RTAS use */ extern unsigned long rtas_rmo_buf; +/* Poweron buffer used for enabling auto ups restart */ +extern unsigned long rtas_poweron_auto; + #define GLOBAL_INTERRUPT_QUEUE 9005 /**