sparc: Annotate of_device_id arrays with const or __initdata.
[deliverable/linux.git] / arch / sparc64 / kernel / power.c
CommitLineData
13077d80 1/* power.c: Power management driver.
1da177e4 2 *
c510b9bf 3 * Copyright (C) 1999, 2007, 2008 David S. Miller (davem@davemloft.net)
1da177e4
LT
4 */
5
1da177e4
LT
6#include <linux/kernel.h>
7#include <linux/module.h>
8#include <linux/init.h>
1da177e4 9#include <linux/interrupt.h>
90bf8116 10#include <linux/pm.h>
a3761780 11#include <linux/reboot.h>
764f2579 12#include <linux/of_device.h>
1da177e4 13
1da177e4 14#include <asm/auxio.h>
abbce6e2 15#include <asm/prom.h>
abbce6e2 16#include <asm/io.h>
22d6a1cb 17#include <asm/sstate.h>
c3c25240 18#include <asm/reboot.h>
1da177e4 19
1da177e4
LT
20/*
21 * sysctl - toggle power-off restriction for serial console
22 * systems in machine_power_off()
23 */
24int scons_pwroff = 1;
25
1da177e4
LT
26static void __iomem *power_reg;
27
13077d80
DM
28static irqreturn_t power_handler(int irq, void *dev_id)
29{
a3761780 30 orderly_poweroff(true);
1da177e4
LT
31
32 /* FIXME: Check registers for status... */
33 return IRQ_HANDLED;
34}
1da177e4 35
1da177e4
LT
36static void (*poweroff_method)(void) = machine_alt_power_off;
37
38void machine_power_off(void)
39{
22d6a1cb 40 sstate_poweroff();
c73fcc84 41 if (strcmp(of_console_device->type, "serial") || scons_pwroff) {
1da177e4
LT
42 if (power_reg) {
43 /* Both register bits seem to have the
44 * same effect, so until I figure out
45 * what the difference is...
46 */
47 writel(AUXIO_PCIO_CPWR_OFF | AUXIO_PCIO_SPWR_OFF, power_reg);
13077d80 48 } else {
1da177e4
LT
49 if (poweroff_method != NULL) {
50 poweroff_method();
51 /* not reached */
52 }
13077d80 53 }
1da177e4
LT
54 }
55 machine_halt();
56}
57
90bf8116
DM
58void (*pm_power_off)(void) = machine_power_off;
59EXPORT_SYMBOL(pm_power_off);
60
690c8fd3 61static int __init has_button_interrupt(unsigned int irq, struct device_node *dp)
1da177e4 62{
13077d80 63 if (irq == 0xffffffff)
1da177e4 64 return 0;
690c8fd3 65 if (!of_find_property(dp, "button", NULL))
1da177e4
LT
66 return 0;
67
68 return 1;
69}
70
abbce6e2 71static int __devinit power_probe(struct of_device *op, const struct of_device_id *match)
1da177e4 72{
abbce6e2
DM
73 struct resource *res = &op->resource[0];
74 unsigned int irq= op->irqs[0];
a2bd4fd1 75
abbce6e2
DM
76 power_reg = of_ioremap(res, 0, 0x4, "power");
77
2a263021 78 printk(KERN_INFO "%s: Control reg at %lx\n",
abbce6e2 79 op->node->name, res->start);
a2bd4fd1 80
1da177e4 81 poweroff_method = machine_halt; /* able to use the standard halt */
a2bd4fd1 82
abbce6e2 83 if (has_button_interrupt(irq, op->node)) {
2256c13b 84 if (request_irq(irq,
00cde674 85 power_handler, 0, "power", NULL) < 0)
13077d80 86 printk(KERN_ERR "power: Cannot setup IRQ handler.\n");
1da177e4 87 }
abbce6e2
DM
88
89 return 0;
1da177e4 90}
a2bd4fd1 91
fd098316 92static struct of_device_id __initdata power_match[] = {
a2bd4fd1
DM
93 {
94 .name = "power",
95 },
96 {},
97};
98
abbce6e2 99static struct of_platform_driver power_driver = {
a2bd4fd1 100 .match_table = power_match,
abbce6e2 101 .probe = power_probe,
a2cd1558
SR
102 .driver = {
103 .name = "power",
104 },
a2bd4fd1
DM
105};
106
c510b9bf 107static int __init power_init(void)
a2bd4fd1 108{
c510b9bf 109 return of_register_driver(&power_driver, &of_platform_bus_type);
a2bd4fd1 110}
c510b9bf
DM
111
112device_initcall(power_init);
This page took 0.331941 seconds and 5 git commands to generate.