diff options
-rw-r--r-- | arch/powerpc/platforms/ps3/setup.c | 12 | ||||
-rw-r--r-- | drivers/ps3/ps3-sys-manager.c | 30 | ||||
-rw-r--r-- | drivers/ps3/sys-manager-core.c | 16 | ||||
-rw-r--r-- | include/asm-powerpc/ps3.h | 5 |
4 files changed, 44 insertions, 19 deletions
diff --git a/arch/powerpc/platforms/ps3/setup.c b/arch/powerpc/platforms/ps3/setup.c index 5c2cbb08eb52..c144669a0d3f 100644 --- a/arch/powerpc/platforms/ps3/setup.c +++ b/arch/powerpc/platforms/ps3/setup.c | |||
@@ -95,6 +95,14 @@ static void ps3_power_off(void) | |||
95 | ps3_sys_manager_power_off(); /* never returns */ | 95 | ps3_sys_manager_power_off(); /* never returns */ |
96 | } | 96 | } |
97 | 97 | ||
98 | static void ps3_halt(void) | ||
99 | { | ||
100 | DBG("%s:%d\n", __func__, __LINE__); | ||
101 | |||
102 | smp_send_stop(); | ||
103 | ps3_sys_manager_halt(); /* never returns */ | ||
104 | } | ||
105 | |||
98 | static void ps3_panic(char *str) | 106 | static void ps3_panic(char *str) |
99 | { | 107 | { |
100 | DBG("%s:%d %s\n", __func__, __LINE__, str); | 108 | DBG("%s:%d %s\n", __func__, __LINE__, str); |
@@ -105,7 +113,8 @@ static void ps3_panic(char *str) | |||
105 | printk(" Please press POWER button.\n"); | 113 | printk(" Please press POWER button.\n"); |
106 | printk("\n"); | 114 | printk("\n"); |
107 | 115 | ||
108 | while(1); | 116 | while(1) |
117 | lv1_pause(1); | ||
109 | } | 118 | } |
110 | 119 | ||
111 | #if defined(CONFIG_FB_PS3) || defined(CONFIG_FB_PS3_MODULE) || \ | 120 | #if defined(CONFIG_FB_PS3) || defined(CONFIG_FB_PS3_MODULE) || \ |
@@ -266,6 +275,7 @@ define_machine(ps3) { | |||
266 | .progress = ps3_progress, | 275 | .progress = ps3_progress, |
267 | .restart = ps3_restart, | 276 | .restart = ps3_restart, |
268 | .power_off = ps3_power_off, | 277 | .power_off = ps3_power_off, |
278 | .halt = ps3_halt, | ||
269 | #if defined(CONFIG_KEXEC) | 279 | #if defined(CONFIG_KEXEC) |
270 | .kexec_cpu_down = ps3_kexec_cpu_down, | 280 | .kexec_cpu_down = ps3_kexec_cpu_down, |
271 | .machine_kexec = default_machine_kexec, | 281 | .machine_kexec = default_machine_kexec, |
diff --git a/drivers/ps3/ps3-sys-manager.c b/drivers/ps3/ps3-sys-manager.c index d4f6f960dd18..1260b01a5361 100644 --- a/drivers/ps3/ps3-sys-manager.c +++ b/drivers/ps3/ps3-sys-manager.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/reboot.h> | 24 | #include <linux/reboot.h> |
25 | 25 | ||
26 | #include <asm/firmware.h> | 26 | #include <asm/firmware.h> |
27 | #include <asm/lv1call.h> | ||
27 | #include <asm/ps3.h> | 28 | #include <asm/ps3.h> |
28 | 29 | ||
29 | #include "vuart.h" | 30 | #include "vuart.h" |
@@ -581,6 +582,23 @@ fail_id: | |||
581 | return -EIO; | 582 | return -EIO; |
582 | } | 583 | } |
583 | 584 | ||
585 | static void ps3_sys_manager_fin(struct ps3_system_bus_device *dev) | ||
586 | { | ||
587 | ps3_sys_manager_send_request_shutdown(dev); | ||
588 | |||
589 | pr_emerg("System Halted, OK to turn off power\n"); | ||
590 | |||
591 | while (ps3_sys_manager_handle_msg(dev)) { | ||
592 | /* pause until next DEC interrupt */ | ||
593 | lv1_pause(0); | ||
594 | } | ||
595 | |||
596 | while (1) { | ||
597 | /* pause, ignoring DEC interrupt */ | ||
598 | lv1_pause(1); | ||
599 | } | ||
600 | } | ||
601 | |||
584 | /** | 602 | /** |
585 | * ps3_sys_manager_final_power_off - The final platform machine_power_off routine. | 603 | * ps3_sys_manager_final_power_off - The final platform machine_power_off routine. |
586 | * | 604 | * |
@@ -602,12 +620,8 @@ static void ps3_sys_manager_final_power_off(struct ps3_system_bus_device *dev) | |||
602 | 620 | ||
603 | ps3_sys_manager_send_next_op(dev, PS3_SM_NEXT_OP_SYS_SHUTDOWN, | 621 | ps3_sys_manager_send_next_op(dev, PS3_SM_NEXT_OP_SYS_SHUTDOWN, |
604 | PS3_SM_WAKE_DEFAULT); | 622 | PS3_SM_WAKE_DEFAULT); |
605 | ps3_sys_manager_send_request_shutdown(dev); | ||
606 | |||
607 | pr_emerg("System Halted, OK to turn off power\n"); | ||
608 | 623 | ||
609 | while (1) | 624 | ps3_sys_manager_fin(dev); |
610 | ps3_sys_manager_handle_msg(dev); | ||
611 | } | 625 | } |
612 | 626 | ||
613 | /** | 627 | /** |
@@ -639,12 +653,8 @@ static void ps3_sys_manager_final_restart(struct ps3_system_bus_device *dev) | |||
639 | ps3_sys_manager_send_attr(dev, 0); | 653 | ps3_sys_manager_send_attr(dev, 0); |
640 | ps3_sys_manager_send_next_op(dev, PS3_SM_NEXT_OP_SYS_REBOOT, | 654 | ps3_sys_manager_send_next_op(dev, PS3_SM_NEXT_OP_SYS_REBOOT, |
641 | PS3_SM_WAKE_DEFAULT); | 655 | PS3_SM_WAKE_DEFAULT); |
642 | ps3_sys_manager_send_request_shutdown(dev); | ||
643 | |||
644 | pr_emerg("System Halted, OK to turn off power\n"); | ||
645 | 656 | ||
646 | while (1) | 657 | ps3_sys_manager_fin(dev); |
647 | ps3_sys_manager_handle_msg(dev); | ||
648 | } | 658 | } |
649 | 659 | ||
650 | /** | 660 | /** |
diff --git a/drivers/ps3/sys-manager-core.c b/drivers/ps3/sys-manager-core.c index 31648f7d9ae1..474225852b63 100644 --- a/drivers/ps3/sys-manager-core.c +++ b/drivers/ps3/sys-manager-core.c | |||
@@ -19,6 +19,7 @@ | |||
19 | */ | 19 | */ |
20 | 20 | ||
21 | #include <linux/kernel.h> | 21 | #include <linux/kernel.h> |
22 | #include <asm/lv1call.h> | ||
22 | #include <asm/ps3.h> | 23 | #include <asm/ps3.h> |
23 | 24 | ||
24 | /** | 25 | /** |
@@ -50,10 +51,7 @@ void ps3_sys_manager_power_off(void) | |||
50 | if (ps3_sys_manager_ops.power_off) | 51 | if (ps3_sys_manager_ops.power_off) |
51 | ps3_sys_manager_ops.power_off(ps3_sys_manager_ops.dev); | 52 | ps3_sys_manager_ops.power_off(ps3_sys_manager_ops.dev); |
52 | 53 | ||
53 | printk(KERN_EMERG "System Halted, OK to turn off power\n"); | 54 | ps3_sys_manager_halt(); |
54 | local_irq_disable(); | ||
55 | while (1) | ||
56 | (void)0; | ||
57 | } | 55 | } |
58 | 56 | ||
59 | void ps3_sys_manager_restart(void) | 57 | void ps3_sys_manager_restart(void) |
@@ -61,8 +59,14 @@ void ps3_sys_manager_restart(void) | |||
61 | if (ps3_sys_manager_ops.restart) | 59 | if (ps3_sys_manager_ops.restart) |
62 | ps3_sys_manager_ops.restart(ps3_sys_manager_ops.dev); | 60 | ps3_sys_manager_ops.restart(ps3_sys_manager_ops.dev); |
63 | 61 | ||
64 | printk(KERN_EMERG "System Halted, OK to turn off power\n"); | 62 | ps3_sys_manager_halt(); |
63 | } | ||
64 | |||
65 | void ps3_sys_manager_halt(void) | ||
66 | { | ||
67 | pr_emerg("System Halted, OK to turn off power\n"); | ||
65 | local_irq_disable(); | 68 | local_irq_disable(); |
66 | while (1) | 69 | while (1) |
67 | (void)0; | 70 | lv1_pause(1); |
68 | } | 71 | } |
72 | |||
diff --git a/include/asm-powerpc/ps3.h b/include/asm-powerpc/ps3.h index 2b693673eff4..d01c701bd27b 100644 --- a/include/asm-powerpc/ps3.h +++ b/include/asm-powerpc/ps3.h | |||
@@ -434,8 +434,9 @@ struct ps3_sys_manager_ops { | |||
434 | }; | 434 | }; |
435 | 435 | ||
436 | void ps3_sys_manager_register_ops(const struct ps3_sys_manager_ops *ops); | 436 | void ps3_sys_manager_register_ops(const struct ps3_sys_manager_ops *ops); |
437 | void ps3_sys_manager_power_off(void); | 437 | void __noreturn ps3_sys_manager_power_off(void); |
438 | void ps3_sys_manager_restart(void); | 438 | void __noreturn ps3_sys_manager_restart(void); |
439 | void __noreturn ps3_sys_manager_halt(void); | ||
439 | 440 | ||
440 | struct ps3_prealloc { | 441 | struct ps3_prealloc { |
441 | const char *name; | 442 | const char *name; |