aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel/power.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc64/kernel/power.c')
-rw-r--r--arch/sparc64/kernel/power.c60
1 files changed, 2 insertions, 58 deletions
diff --git a/arch/sparc64/kernel/power.c b/arch/sparc64/kernel/power.c
index 8dd4294ad21e..7471e844724d 100644
--- a/arch/sparc64/kernel/power.c
+++ b/arch/sparc64/kernel/power.c
@@ -12,13 +12,13 @@
12#include <linux/interrupt.h> 12#include <linux/interrupt.h>
13#include <linux/pm.h> 13#include <linux/pm.h>
14#include <linux/syscalls.h> 14#include <linux/syscalls.h>
15#include <linux/reboot.h>
15 16
16#include <asm/system.h> 17#include <asm/system.h>
17#include <asm/auxio.h> 18#include <asm/auxio.h>
18#include <asm/prom.h> 19#include <asm/prom.h>
19#include <asm/of_device.h> 20#include <asm/of_device.h>
20#include <asm/io.h> 21#include <asm/io.h>
21#include <asm/power.h>
22#include <asm/sstate.h> 22#include <asm/sstate.h>
23 23
24#include <linux/unistd.h> 24#include <linux/unistd.h>
@@ -31,20 +31,9 @@ int scons_pwroff = 1;
31 31
32static void __iomem *power_reg; 32static void __iomem *power_reg;
33 33
34static DECLARE_WAIT_QUEUE_HEAD(powerd_wait);
35static int button_pressed;
36
37void wake_up_powerd(void)
38{
39 if (button_pressed == 0) {
40 button_pressed = 1;
41 wake_up(&powerd_wait);
42 }
43}
44
45static irqreturn_t power_handler(int irq, void *dev_id) 34static irqreturn_t power_handler(int irq, void *dev_id)
46{ 35{
47 wake_up_powerd(); 36 orderly_poweroff(true);
48 37
49 /* FIXME: Check registers for status... */ 38 /* FIXME: Check registers for status... */
50 return IRQ_HANDLED; 39 return IRQ_HANDLED;
@@ -77,48 +66,6 @@ void machine_power_off(void)
77void (*pm_power_off)(void) = machine_power_off; 66void (*pm_power_off)(void) = machine_power_off;
78EXPORT_SYMBOL(pm_power_off); 67EXPORT_SYMBOL(pm_power_off);
79 68
80static int powerd(void *__unused)
81{
82 static char *envp[] = { "HOME=/", "TERM=linux", "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL };
83 char *argv[] = { "/sbin/shutdown", "-h", "now", NULL };
84 DECLARE_WAITQUEUE(wait, current);
85
86 daemonize("powerd");
87
88 add_wait_queue(&powerd_wait, &wait);
89
90 for (;;) {
91 set_task_state(current, TASK_INTERRUPTIBLE);
92 if (button_pressed)
93 break;
94 flush_signals(current);
95 schedule();
96 }
97 __set_current_state(TASK_RUNNING);
98 remove_wait_queue(&powerd_wait, &wait);
99
100 /* Ok, down we go... */
101 button_pressed = 0;
102 if (kernel_execve("/sbin/shutdown", argv, envp) < 0) {
103 printk(KERN_ERR "powerd: shutdown execution failed\n");
104 machine_power_off();
105 }
106 return 0;
107}
108
109int start_powerd(void)
110{
111 int err;
112
113 err = kernel_thread(powerd, NULL, CLONE_FS);
114 if (err < 0)
115 printk(KERN_ERR "power: Failed to start power daemon.\n");
116 else
117 printk(KERN_INFO "power: powerd running.\n");
118
119 return err;
120}
121
122static int __init has_button_interrupt(unsigned int irq, struct device_node *dp) 69static int __init has_button_interrupt(unsigned int irq, struct device_node *dp)
123{ 70{
124 if (irq == 0xffffffff) 71 if (irq == 0xffffffff)
@@ -142,9 +89,6 @@ static int __devinit power_probe(struct of_device *op, const struct of_device_id
142 poweroff_method = machine_halt; /* able to use the standard halt */ 89 poweroff_method = machine_halt; /* able to use the standard halt */
143 90
144 if (has_button_interrupt(irq, op->node)) { 91 if (has_button_interrupt(irq, op->node)) {
145 if (start_powerd() < 0)
146 return 0;
147
148 if (request_irq(irq, 92 if (request_irq(irq,
149 power_handler, 0, "power", NULL) < 0) 93 power_handler, 0, "power", NULL) < 0)
150 printk(KERN_ERR "power: Cannot setup IRQ handler.\n"); 94 printk(KERN_ERR "power: Cannot setup IRQ handler.\n");