~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/sparc64/kernel/power.c

Version: ~ [ linux-5.1.2 ] ~ [ linux-5.0.16 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.43 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.119 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.176 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.179 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.139 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.67 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.39.4 ] ~ [ linux-2.6.38.8 ] ~ [ linux-2.6.37.6 ] ~ [ linux-2.6.36.4 ] ~ [ linux-2.6.35.14 ] ~ [ linux-2.6.34.15 ] ~ [ linux-2.6.33.20 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp