aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ps3
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ps3')
-rw-r--r--drivers/ps3/ps3-sys-manager.c74
-rw-r--r--drivers/ps3/sys-manager-core.c16
2 files changed, 73 insertions, 17 deletions
diff --git a/drivers/ps3/ps3-sys-manager.c b/drivers/ps3/ps3-sys-manager.c
index d4f6f960dd18..7605453b74fd 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"
@@ -187,6 +188,7 @@ enum ps3_sys_manager_next_op {
187 * controller, and bluetooth controller. 188 * controller, and bluetooth controller.
188 * @PS3_SM_WAKE_RTC: 189 * @PS3_SM_WAKE_RTC:
189 * @PS3_SM_WAKE_RTC_ERROR: 190 * @PS3_SM_WAKE_RTC_ERROR:
191 * @PS3_SM_WAKE_W_O_L: Ether or wireless LAN.
190 * @PS3_SM_WAKE_P_O_R: Power on reset. 192 * @PS3_SM_WAKE_P_O_R: Power on reset.
191 * 193 *
192 * Additional wakeup sources when specifying PS3_SM_NEXT_OP_SYS_SHUTDOWN. 194 * Additional wakeup sources when specifying PS3_SM_NEXT_OP_SYS_SHUTDOWN.
@@ -200,10 +202,19 @@ enum ps3_sys_manager_wake_source {
200 PS3_SM_WAKE_DEFAULT = 0, 202 PS3_SM_WAKE_DEFAULT = 0,
201 PS3_SM_WAKE_RTC = 0x00000040, 203 PS3_SM_WAKE_RTC = 0x00000040,
202 PS3_SM_WAKE_RTC_ERROR = 0x00000080, 204 PS3_SM_WAKE_RTC_ERROR = 0x00000080,
205 PS3_SM_WAKE_W_O_L = 0x00000400,
203 PS3_SM_WAKE_P_O_R = 0x80000000, 206 PS3_SM_WAKE_P_O_R = 0x80000000,
204}; 207};
205 208
206/** 209/**
210 * user_wake_sources - User specified wakeup sources.
211 *
212 * Logical OR of enum ps3_sys_manager_wake_source types.
213 */
214
215static u32 user_wake_sources = PS3_SM_WAKE_DEFAULT;
216
217/**
207 * enum ps3_sys_manager_cmd - Command from system manager to guest. 218 * enum ps3_sys_manager_cmd - Command from system manager to guest.
208 * 219 *
209 * The guest completes the actions needed, then acks or naks the command via 220 * The guest completes the actions needed, then acks or naks the command via
@@ -581,6 +592,23 @@ fail_id:
581 return -EIO; 592 return -EIO;
582} 593}
583 594
595static void ps3_sys_manager_fin(struct ps3_system_bus_device *dev)
596{
597 ps3_sys_manager_send_request_shutdown(dev);
598
599 pr_emerg("System Halted, OK to turn off power\n");
600
601 while (ps3_sys_manager_handle_msg(dev)) {
602 /* pause until next DEC interrupt */
603 lv1_pause(0);
604 }
605
606 while (1) {
607 /* pause, ignoring DEC interrupt */
608 lv1_pause(1);
609 }
610}
611
584/** 612/**
585 * ps3_sys_manager_final_power_off - The final platform machine_power_off routine. 613 * ps3_sys_manager_final_power_off - The final platform machine_power_off routine.
586 * 614 *
@@ -601,13 +629,9 @@ static void ps3_sys_manager_final_power_off(struct ps3_system_bus_device *dev)
601 ps3_vuart_cancel_async(dev); 629 ps3_vuart_cancel_async(dev);
602 630
603 ps3_sys_manager_send_next_op(dev, PS3_SM_NEXT_OP_SYS_SHUTDOWN, 631 ps3_sys_manager_send_next_op(dev, PS3_SM_NEXT_OP_SYS_SHUTDOWN,
604 PS3_SM_WAKE_DEFAULT); 632 user_wake_sources);
605 ps3_sys_manager_send_request_shutdown(dev);
606
607 pr_emerg("System Halted, OK to turn off power\n");
608 633
609 while (1) 634 ps3_sys_manager_fin(dev);
610 ps3_sys_manager_handle_msg(dev);
611} 635}
612 636
613/** 637/**
@@ -638,14 +662,42 @@ static void ps3_sys_manager_final_restart(struct ps3_system_bus_device *dev)
638 662
639 ps3_sys_manager_send_attr(dev, 0); 663 ps3_sys_manager_send_attr(dev, 0);
640 ps3_sys_manager_send_next_op(dev, PS3_SM_NEXT_OP_SYS_REBOOT, 664 ps3_sys_manager_send_next_op(dev, PS3_SM_NEXT_OP_SYS_REBOOT,
641 PS3_SM_WAKE_DEFAULT); 665 user_wake_sources);
642 ps3_sys_manager_send_request_shutdown(dev);
643 666
644 pr_emerg("System Halted, OK to turn off power\n"); 667 ps3_sys_manager_fin(dev);
668}
669
670/**
671 * ps3_sys_manager_get_wol - Get wake-on-lan setting.
672 */
673
674int ps3_sys_manager_get_wol(void)
675{
676 pr_debug("%s:%d\n", __func__, __LINE__);
677
678 return (user_wake_sources & PS3_SM_WAKE_W_O_L) != 0;
679}
680EXPORT_SYMBOL_GPL(ps3_sys_manager_get_wol);
681
682/**
683 * ps3_sys_manager_set_wol - Set wake-on-lan setting.
684 */
685
686void ps3_sys_manager_set_wol(int state)
687{
688 static DEFINE_MUTEX(mutex);
689
690 mutex_lock(&mutex);
691
692 pr_debug("%s:%d: %d\n", __func__, __LINE__, state);
645 693
646 while (1) 694 if (state)
647 ps3_sys_manager_handle_msg(dev); 695 user_wake_sources |= PS3_SM_WAKE_W_O_L;
696 else
697 user_wake_sources &= ~PS3_SM_WAKE_W_O_L;
698 mutex_unlock(&mutex);
648} 699}
700EXPORT_SYMBOL_GPL(ps3_sys_manager_set_wol);
649 701
650/** 702/**
651 * ps3_sys_manager_work - Asynchronous read handler. 703 * ps3_sys_manager_work - Asynchronous read handler.
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
59void ps3_sys_manager_restart(void) 57void 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
65void 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