diff options
author | Manish Ahuja <ahuja@austin.ibm.com> | 2007-02-08 17:01:17 -0500 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2007-02-16 18:22:50 -0500 |
commit | 5d30bf309717a518d0c4180af41650d4dcd3bb38 (patch) | |
tree | d76a078f1b1737092528a4305357bc6384aeb041 /arch | |
parent | aebcbf39be0aadded32f4cd82c1d88a8cac4614b (diff) |
[POWERPC] pseries: Enabling auto poweron after power is restored.
During power outages, the UPS notifies the system for a shutdown.
In the current setup, it isn't possible to poweron when power is
restored. This patch fixes the issue by calling the right
ibm,power-off-ups token during such events. It also adds a sysfs
interface so userspace can specify whether or not to power on when
power is restored.
Signed-off-by: Manish Ahuja <ahuja@austin.ibm.com>
Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/powerpc/platforms/pseries/Makefile | 2 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/power.c | 87 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/pseries.h | 3 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/setup.c | 30 |
4 files changed, 120 insertions, 2 deletions
diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile index dc0583bdbc63..2dfd05095a25 100644 --- a/arch/powerpc/platforms/pseries/Makefile +++ b/arch/powerpc/platforms/pseries/Makefile | |||
@@ -4,7 +4,7 @@ endif | |||
4 | 4 | ||
5 | obj-y := pci.o lpar.o hvCall.o nvram.o reconfig.o \ | 5 | obj-y := pci.o lpar.o hvCall.o nvram.o reconfig.o \ |
6 | setup.o iommu.o ras.o rtasd.o pci_dlpar.o \ | 6 | setup.o iommu.o ras.o rtasd.o pci_dlpar.o \ |
7 | firmware.o | 7 | firmware.o power.o |
8 | obj-$(CONFIG_SMP) += smp.o | 8 | obj-$(CONFIG_SMP) += smp.o |
9 | obj-$(CONFIG_XICS) += xics.o | 9 | obj-$(CONFIG_XICS) += xics.o |
10 | obj-$(CONFIG_SCANLOG) += scanlog.o | 10 | obj-$(CONFIG_SCANLOG) += scanlog.o |
diff --git a/arch/powerpc/platforms/pseries/power.c b/arch/powerpc/platforms/pseries/power.c new file mode 100644 index 000000000000..2624b71df73d --- /dev/null +++ b/arch/powerpc/platforms/pseries/power.c | |||
@@ -0,0 +1,87 @@ | |||
1 | /* | ||
2 | * Interface for power-management for ppc64 compliant platform | ||
3 | * | ||
4 | * Manish Ahuja <mahuja@us.ibm.com> | ||
5 | * | ||
6 | * Feb 2007 | ||
7 | * | ||
8 | * Copyright (C) 2007 IBM Corporation. | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; version 2 of the License. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
22 | */ | ||
23 | |||
24 | #include <linux/kobject.h> | ||
25 | #include <linux/string.h> | ||
26 | #include <linux/errno.h> | ||
27 | #include <linux/init.h> | ||
28 | |||
29 | unsigned long rtas_poweron_auto; /* default and normal state is 0 */ | ||
30 | |||
31 | static ssize_t auto_poweron_show(struct subsystem *subsys, char *buf) | ||
32 | { | ||
33 | return sprintf(buf, "%lu\n", rtas_poweron_auto); | ||
34 | } | ||
35 | |||
36 | static ssize_t | ||
37 | auto_poweron_store(struct subsystem *subsys, const char *buf, size_t n) | ||
38 | { | ||
39 | int ret; | ||
40 | unsigned long ups_restart; | ||
41 | ret = sscanf(buf, "%lu", &ups_restart); | ||
42 | |||
43 | if ((ret == 1) && ((ups_restart == 1) || (ups_restart == 0))){ | ||
44 | rtas_poweron_auto = ups_restart; | ||
45 | return n; | ||
46 | } | ||
47 | return -EINVAL; | ||
48 | } | ||
49 | |||
50 | static struct subsys_attribute auto_poweron_attr = { | ||
51 | .attr = { | ||
52 | .name = __stringify(auto_poweron), | ||
53 | .mode = 0644, | ||
54 | }, | ||
55 | .show = auto_poweron_show, | ||
56 | .store = auto_poweron_store, | ||
57 | }; | ||
58 | |||
59 | #ifndef CONFIG_PM | ||
60 | decl_subsys(power,NULL,NULL); | ||
61 | |||
62 | static struct attribute *g[] = { | ||
63 | &auto_poweron_attr.attr, | ||
64 | NULL, | ||
65 | }; | ||
66 | |||
67 | static struct attribute_group attr_group = { | ||
68 | .attrs = g, | ||
69 | }; | ||
70 | |||
71 | static int __init pm_init(void) | ||
72 | { | ||
73 | int error = subsystem_register(&power_subsys); | ||
74 | if (!error) | ||
75 | error = sysfs_create_group(&power_subsys.kset.kobj,&attr_group); | ||
76 | return error; | ||
77 | } | ||
78 | core_initcall(pm_init); | ||
79 | #else | ||
80 | extern struct subsystem power_subsys; | ||
81 | |||
82 | static int __init apo_pm_init(void) | ||
83 | { | ||
84 | return (subsys_create_file(&power_subsys, &auto_poweron_attr)); | ||
85 | } | ||
86 | __initcall(apo_pm_init); | ||
87 | #endif | ||
diff --git a/arch/powerpc/platforms/pseries/pseries.h b/arch/powerpc/platforms/pseries/pseries.h index 35264f9af0ff..22bc01989749 100644 --- a/arch/powerpc/platforms/pseries/pseries.h +++ b/arch/powerpc/platforms/pseries/pseries.h | |||
@@ -33,4 +33,7 @@ static inline void setup_kexec_cpu_down_xics(void) { } | |||
33 | static inline void setup_kexec_cpu_down_mpic(void) { } | 33 | static inline void setup_kexec_cpu_down_mpic(void) { } |
34 | #endif | 34 | #endif |
35 | 35 | ||
36 | /* Poweron flag used for enabling auto ups restart */ | ||
37 | extern unsigned long rtas_poweron_auto; | ||
38 | |||
36 | #endif /* _PSERIES_PSERIES_H */ | 39 | #endif /* _PSERIES_PSERIES_H */ |
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index 435a04596526..34aff47b1f55 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c | |||
@@ -486,6 +486,34 @@ static int pSeries_pci_probe_mode(struct pci_bus *bus) | |||
486 | return PCI_PROBE_NORMAL; | 486 | return PCI_PROBE_NORMAL; |
487 | } | 487 | } |
488 | 488 | ||
489 | /** | ||
490 | * pSeries_power_off - tell firmware about how to power off the system. | ||
491 | * | ||
492 | * This function calls either the power-off rtas token in normal cases | ||
493 | * or the ibm,power-off-ups token (if present & requested) in case of | ||
494 | * a power failure. If power-off token is used, power on will only be | ||
495 | * possible with power button press. If ibm,power-off-ups token is used | ||
496 | * it will allow auto poweron after power is restored. | ||
497 | */ | ||
498 | void pSeries_power_off(void) | ||
499 | { | ||
500 | int rc; | ||
501 | int rtas_poweroff_ups_token = rtas_token("ibm,power-off-ups"); | ||
502 | |||
503 | if (rtas_flash_term_hook) | ||
504 | rtas_flash_term_hook(SYS_POWER_OFF); | ||
505 | |||
506 | if (rtas_poweron_auto == 0 || | ||
507 | rtas_poweroff_ups_token == RTAS_UNKNOWN_SERVICE) { | ||
508 | rc = rtas_call(rtas_token("power-off"), 2, 1, NULL, -1, -1); | ||
509 | printk(KERN_INFO "RTAS power-off returned %d\n", rc); | ||
510 | } else { | ||
511 | rc = rtas_call(rtas_poweroff_ups_token, 0, 1, NULL); | ||
512 | printk(KERN_INFO "RTAS ibm,power-off-ups returned %d\n", rc); | ||
513 | } | ||
514 | for (;;); | ||
515 | } | ||
516 | |||
489 | define_machine(pseries) { | 517 | define_machine(pseries) { |
490 | .name = "pSeries", | 518 | .name = "pSeries", |
491 | .probe = pSeries_probe, | 519 | .probe = pSeries_probe, |
@@ -496,7 +524,7 @@ define_machine(pseries) { | |||
496 | .pcibios_fixup = pSeries_final_fixup, | 524 | .pcibios_fixup = pSeries_final_fixup, |
497 | .pci_probe_mode = pSeries_pci_probe_mode, | 525 | .pci_probe_mode = pSeries_pci_probe_mode, |
498 | .restart = rtas_restart, | 526 | .restart = rtas_restart, |
499 | .power_off = rtas_power_off, | 527 | .power_off = pSeries_power_off, |
500 | .halt = rtas_halt, | 528 | .halt = rtas_halt, |
501 | .panic = rtas_os_term, | 529 | .panic = rtas_os_term, |
502 | .get_boot_time = rtas_get_boot_time, | 530 | .get_boot_time = rtas_get_boot_time, |