OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [arch/] [sparc64/] [kernel/] [power.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/* $Id: power.c,v 1.1.1.1 2004-04-15 01:34:45 phoenix Exp $
2
 * power.c: Power management driver.
3
 *
4
 * Copyright (C) 1999 David S. Miller (davem@redhat.com)
5
 */
6
 
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>
13
 
14
#include <asm/ebus.h>
15
#include <asm/auxio.h>
16
 
17
#define __KERNEL_SYSCALLS__
18
#include <linux/unistd.h>
19
 
20
#ifdef CONFIG_PCI
21
static unsigned long power_reg = 0UL;
22
 
23
static DECLARE_WAIT_QUEUE_HEAD(powerd_wait);
24
static int button_pressed;
25
 
26
static void power_handler(int irq, void *dev_id, struct pt_regs *regs)
27
{
28
        if (button_pressed == 0) {
29
                wake_up(&powerd_wait);
30
                button_pressed = 1;
31
        }
32
}
33
#endif /* CONFIG_PCI */
34
 
35
extern void machine_halt(void);
36
extern void machine_alt_power_off(void);
37
static void (*poweroff_method)(void) = machine_alt_power_off;
38
 
39
extern int serial_console;
40
 
41
void machine_power_off(void)
42
{
43
        if (!serial_console) {
44
#ifdef CONFIG_PCI
45
                if (power_reg != 0UL) {
46
                        /* Both register bits seem to have the
47
                         * same effect, so until I figure out
48
                         * what the difference is...
49
                         */
50
                        writel(AUXIO_PCIO_CPWR_OFF | AUXIO_PCIO_SPWR_OFF, power_reg);
51
                } else
52
#endif /* CONFIG_PCI */
53
                        if (poweroff_method != NULL) {
54
                                poweroff_method();
55
                                /* not reached */
56
                        }
57
        }
58
        machine_halt();
59
}
60
 
61
#ifdef CONFIG_PCI
62
static int powerd(void *__unused)
63
{
64
        static char *envp[] = { "HOME=/", "TERM=linux", "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL };
65
        char *argv[] = { "/sbin/shutdown", "-h", "now", NULL };
66
 
67
        daemonize();
68
        sprintf(current->comm, "powerd");
69
 
70
again:
71
        while (button_pressed == 0) {
72
                spin_lock_irq(&current->sigmask_lock);
73
                flush_signals(current);
74
                spin_unlock_irq(&current->sigmask_lock);
75
                interruptible_sleep_on(&powerd_wait);
76
        }
77
 
78
        /* Ok, down we go... */
79
        if (execve("/sbin/shutdown", argv, envp) < 0) {
80
                printk("powerd: shutdown execution failed\n");
81
                button_pressed = 0;
82
                goto again;
83
        }
84
        return 0;
85
}
86
 
87
static int __init has_button_interrupt(struct linux_ebus_device *edev)
88
{
89
        if (edev->irqs[0] == PCI_IRQ_NONE)
90
                return 0;
91
        if (!prom_node_has_property(edev->prom_node, "button"))
92
                return 0;
93
 
94
        return 1;
95
}
96
 
97
void __init power_init(void)
98
{
99
        struct linux_ebus *ebus;
100
        struct linux_ebus_device *edev;
101
        static int invoked;
102
 
103
        if (invoked)
104
                return;
105
        invoked = 1;
106
 
107
        for_each_ebus(ebus) {
108
                for_each_ebusdev(edev, ebus) {
109
                        if (!strcmp(edev->prom_name, "power"))
110
                                goto found;
111
                }
112
        }
113
        return;
114
 
115
found:
116
        power_reg = (unsigned long)ioremap(edev->resource[0].start, 0x4);
117
        printk("power: Control reg at %016lx ... ", power_reg);
118
        poweroff_method = machine_halt; /* able to use the standard poweroff */
119
        if (has_button_interrupt(edev)) {
120
                if (kernel_thread(powerd, 0, CLONE_FS) < 0) {
121
                        printk("Failed to start power daemon.\n");
122
                        return;
123
                }
124
                printk("powerd running.\n");
125
 
126
                if (request_irq(edev->irqs[0],
127
                                power_handler, SA_SHIRQ, "power",
128
                                (void *) power_reg) < 0)
129
                        printk("power: Error, cannot register IRQ handler.\n");
130
        } else {
131
                printk("not using powerd.\n");
132
        }
133
}
134
#endif /* CONFIG_PCI */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.