1 /* $Id: power.c,v 1.4 1999/08/31 18:22:05 davem Exp $ 2 * power.c: Power management driver. 4 * Copyright (C) 1999 David S. Miller (davem@redhat.com) 7 #include <linux/config.h> 8 #include <linux/kernel.h> 9 #include <linux/init.h> 10 #include <linux/sched.h> 11 #include <linux/signal.h> 12 #include <linux/delay.h> 16 #define __KERNEL_SYSCALLS__ 17 #include <linux/unistd.h> 20 static unsigned long power_reg
=0UL; 21 #define POWER_SYSTEM_OFF (1 << 0) 22 #define POWER_COURTESY_OFF (1 << 1) 24 staticDECLARE_WAIT_QUEUE_HEAD(powerd_wait
); 25 static int button_pressed
=0; 27 static voidpower_handler(int irq
,void*dev_id
,struct pt_regs
*regs
) 29 if(button_pressed
==0) { 30 wake_up(&powerd_wait
); 34 #endif/* CONFIG_PCI */ 36 externvoidmachine_halt(void); 38 voidmachine_power_off(void) 42 /* Both register bits seem to have the 43 * same effect, so until I figure out 44 * what the difference is... 46 writel(POWER_COURTESY_OFF
| POWER_SYSTEM_OFF
, power_reg
); 48 #endif/* CONFIG_PCI */ 53 static intpowerd(void*__unused
) 55 static char*envp
[] = {"HOME=/","TERM=linux","PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL
}; 56 char*argv
[] = {"/usr/bin/shutdown","-h","now", NULL
}; 60 sprintf(current
->comm
,"powerd"); 63 while(button_pressed
==0) { 64 spin_lock_irq(¤t
->sigmask_lock
); 65 flush_signals(current
); 66 spin_unlock_irq(¤t
->sigmask_lock
); 67 interruptible_sleep_on(&powerd_wait
); 70 /* Ok, down we go... */ 71 if(execve("/usr/bin/shutdown", argv
, envp
) <0) { 72 printk("powerd: shutdown execution failed\n"); 79 void __init
power_init(void) 81 struct linux_ebus
*ebus
; 82 struct linux_ebus_device
*edev
; 85 for_each_ebusdev(edev
, ebus
) { 86 if(!strcmp(edev
->prom_name
,"power")) 93 power_reg
= edev
->resource
[0].start
; 94 printk("power: Control reg at %016lx ... ", power_reg
); 95 if(kernel_thread(powerd
,0, CLONE_FS
) <0) { 96 printk("Failed to start power daemon.\n"); 99 printk("powerd running.\n"); 100 if(request_irq(edev
->irqs
[0], 101 power_handler
, SA_SHIRQ
,"power", 102 (void*) power_reg
) <0) 103 printk("power: Error, cannot register IRQ handler.\n"); 105 #endif/* CONFIG_PCI */