mirror of
https://github.com/adulau/aha.git
synced 2024-12-27 19:26:25 +00:00
[POWERPC] PS3: Save power in busy loops on halt
PS3 save power on halt: - Replace infinite busy loops by smarter loops calling lv1_pause() to save power. - Add ps3_halt() and ps3_sys_manager_halt(). - Add __noreturn annotations. Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com> Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com> Signed-off-by: Paul Mackerras <paulus@samba.org>
This commit is contained in:
parent
5761eaa3a5
commit
ca052f7924
4 changed files with 44 additions and 19 deletions
|
@ -95,6 +95,14 @@ static void ps3_power_off(void)
|
||||||
ps3_sys_manager_power_off(); /* never returns */
|
ps3_sys_manager_power_off(); /* never returns */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ps3_halt(void)
|
||||||
|
{
|
||||||
|
DBG("%s:%d\n", __func__, __LINE__);
|
||||||
|
|
||||||
|
smp_send_stop();
|
||||||
|
ps3_sys_manager_halt(); /* never returns */
|
||||||
|
}
|
||||||
|
|
||||||
static void ps3_panic(char *str)
|
static void ps3_panic(char *str)
|
||||||
{
|
{
|
||||||
DBG("%s:%d %s\n", __func__, __LINE__, str);
|
DBG("%s:%d %s\n", __func__, __LINE__, str);
|
||||||
|
@ -105,7 +113,8 @@ static void ps3_panic(char *str)
|
||||||
printk(" Please press POWER button.\n");
|
printk(" Please press POWER button.\n");
|
||||||
printk("\n");
|
printk("\n");
|
||||||
|
|
||||||
while(1);
|
while(1)
|
||||||
|
lv1_pause(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(CONFIG_FB_PS3) || defined(CONFIG_FB_PS3_MODULE) || \
|
#if defined(CONFIG_FB_PS3) || defined(CONFIG_FB_PS3_MODULE) || \
|
||||||
|
@ -266,6 +275,7 @@ define_machine(ps3) {
|
||||||
.progress = ps3_progress,
|
.progress = ps3_progress,
|
||||||
.restart = ps3_restart,
|
.restart = ps3_restart,
|
||||||
.power_off = ps3_power_off,
|
.power_off = ps3_power_off,
|
||||||
|
.halt = ps3_halt,
|
||||||
#if defined(CONFIG_KEXEC)
|
#if defined(CONFIG_KEXEC)
|
||||||
.kexec_cpu_down = ps3_kexec_cpu_down,
|
.kexec_cpu_down = ps3_kexec_cpu_down,
|
||||||
.machine_kexec = default_machine_kexec,
|
.machine_kexec = default_machine_kexec,
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include <linux/reboot.h>
|
#include <linux/reboot.h>
|
||||||
|
|
||||||
#include <asm/firmware.h>
|
#include <asm/firmware.h>
|
||||||
|
#include <asm/lv1call.h>
|
||||||
#include <asm/ps3.h>
|
#include <asm/ps3.h>
|
||||||
|
|
||||||
#include "vuart.h"
|
#include "vuart.h"
|
||||||
|
@ -581,6 +582,23 @@ fail_id:
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ps3_sys_manager_fin(struct ps3_system_bus_device *dev)
|
||||||
|
{
|
||||||
|
ps3_sys_manager_send_request_shutdown(dev);
|
||||||
|
|
||||||
|
pr_emerg("System Halted, OK to turn off power\n");
|
||||||
|
|
||||||
|
while (ps3_sys_manager_handle_msg(dev)) {
|
||||||
|
/* pause until next DEC interrupt */
|
||||||
|
lv1_pause(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
/* pause, ignoring DEC interrupt */
|
||||||
|
lv1_pause(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ps3_sys_manager_final_power_off - The final platform machine_power_off routine.
|
* ps3_sys_manager_final_power_off - The final platform machine_power_off routine.
|
||||||
*
|
*
|
||||||
|
@ -602,12 +620,8 @@ static void ps3_sys_manager_final_power_off(struct ps3_system_bus_device *dev)
|
||||||
|
|
||||||
ps3_sys_manager_send_next_op(dev, PS3_SM_NEXT_OP_SYS_SHUTDOWN,
|
ps3_sys_manager_send_next_op(dev, PS3_SM_NEXT_OP_SYS_SHUTDOWN,
|
||||||
PS3_SM_WAKE_DEFAULT);
|
PS3_SM_WAKE_DEFAULT);
|
||||||
ps3_sys_manager_send_request_shutdown(dev);
|
|
||||||
|
|
||||||
pr_emerg("System Halted, OK to turn off power\n");
|
ps3_sys_manager_fin(dev);
|
||||||
|
|
||||||
while (1)
|
|
||||||
ps3_sys_manager_handle_msg(dev);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -639,12 +653,8 @@ static void ps3_sys_manager_final_restart(struct ps3_system_bus_device *dev)
|
||||||
ps3_sys_manager_send_attr(dev, 0);
|
ps3_sys_manager_send_attr(dev, 0);
|
||||||
ps3_sys_manager_send_next_op(dev, PS3_SM_NEXT_OP_SYS_REBOOT,
|
ps3_sys_manager_send_next_op(dev, PS3_SM_NEXT_OP_SYS_REBOOT,
|
||||||
PS3_SM_WAKE_DEFAULT);
|
PS3_SM_WAKE_DEFAULT);
|
||||||
ps3_sys_manager_send_request_shutdown(dev);
|
|
||||||
|
|
||||||
pr_emerg("System Halted, OK to turn off power\n");
|
ps3_sys_manager_fin(dev);
|
||||||
|
|
||||||
while (1)
|
|
||||||
ps3_sys_manager_handle_msg(dev);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
|
#include <asm/lv1call.h>
|
||||||
#include <asm/ps3.h>
|
#include <asm/ps3.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -50,10 +51,7 @@ void ps3_sys_manager_power_off(void)
|
||||||
if (ps3_sys_manager_ops.power_off)
|
if (ps3_sys_manager_ops.power_off)
|
||||||
ps3_sys_manager_ops.power_off(ps3_sys_manager_ops.dev);
|
ps3_sys_manager_ops.power_off(ps3_sys_manager_ops.dev);
|
||||||
|
|
||||||
printk(KERN_EMERG "System Halted, OK to turn off power\n");
|
ps3_sys_manager_halt();
|
||||||
local_irq_disable();
|
|
||||||
while (1)
|
|
||||||
(void)0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ps3_sys_manager_restart(void)
|
void ps3_sys_manager_restart(void)
|
||||||
|
@ -61,8 +59,14 @@ void ps3_sys_manager_restart(void)
|
||||||
if (ps3_sys_manager_ops.restart)
|
if (ps3_sys_manager_ops.restart)
|
||||||
ps3_sys_manager_ops.restart(ps3_sys_manager_ops.dev);
|
ps3_sys_manager_ops.restart(ps3_sys_manager_ops.dev);
|
||||||
|
|
||||||
printk(KERN_EMERG "System Halted, OK to turn off power\n");
|
ps3_sys_manager_halt();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ps3_sys_manager_halt(void)
|
||||||
|
{
|
||||||
|
pr_emerg("System Halted, OK to turn off power\n");
|
||||||
local_irq_disable();
|
local_irq_disable();
|
||||||
while (1)
|
while (1)
|
||||||
(void)0;
|
lv1_pause(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -434,8 +434,9 @@ struct ps3_sys_manager_ops {
|
||||||
};
|
};
|
||||||
|
|
||||||
void ps3_sys_manager_register_ops(const struct ps3_sys_manager_ops *ops);
|
void ps3_sys_manager_register_ops(const struct ps3_sys_manager_ops *ops);
|
||||||
void ps3_sys_manager_power_off(void);
|
void __noreturn ps3_sys_manager_power_off(void);
|
||||||
void ps3_sys_manager_restart(void);
|
void __noreturn ps3_sys_manager_restart(void);
|
||||||
|
void __noreturn ps3_sys_manager_halt(void);
|
||||||
|
|
||||||
struct ps3_prealloc {
|
struct ps3_prealloc {
|
||||||
const char *name;
|
const char *name;
|
||||||
|
|
Loading…
Reference in a new issue