Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5d30bf30 authored by Manish Ahuja's avatar Manish Ahuja Committed by Paul Mackerras
Browse files

[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: default avatarManish Ahuja <ahuja@austin.ibm.com>
Signed-off-by: default avatarPaul Mackerras <paulus@samba.org>
parent aebcbf39
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -4,7 +4,7 @@ endif


obj-y			:= pci.o lpar.o hvCall.o nvram.o reconfig.o \
obj-y			:= pci.o lpar.o hvCall.o nvram.o reconfig.o \
			   setup.o iommu.o ras.o rtasd.o pci_dlpar.o \
			   setup.o iommu.o ras.o rtasd.o pci_dlpar.o \
			   firmware.o
			   firmware.o power.o
obj-$(CONFIG_SMP)	+= smp.o
obj-$(CONFIG_SMP)	+= smp.o
obj-$(CONFIG_XICS)	+= xics.o
obj-$(CONFIG_XICS)	+= xics.o
obj-$(CONFIG_SCANLOG)	+= scanlog.o
obj-$(CONFIG_SCANLOG)	+= scanlog.o
+87 −0
Original line number Original line Diff line number Diff line
/*
 *  Interface for power-management for ppc64 compliant platform
 *
 *  Manish Ahuja <mahuja@us.ibm.com>
 *
 *  Feb 2007
 *
 *  Copyright (C) 2007 IBM Corporation.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; version 2 of the License.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include <linux/kobject.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/init.h>

unsigned long rtas_poweron_auto; /* default and normal state is 0 */

static ssize_t auto_poweron_show(struct subsystem *subsys, char *buf)
{
        return sprintf(buf, "%lu\n", rtas_poweron_auto);
}

static ssize_t
auto_poweron_store(struct subsystem *subsys, const char *buf, size_t n)
{
	int ret;
	unsigned long ups_restart;
	ret = sscanf(buf, "%lu", &ups_restart);

	if ((ret == 1) && ((ups_restart == 1) || (ups_restart == 0))){
		rtas_poweron_auto = ups_restart;
		return n;
	}
	return -EINVAL;
}

static struct subsys_attribute auto_poweron_attr = {
        .attr   = {
                .name = __stringify(auto_poweron),
                .mode = 0644,
        },
        .show   = auto_poweron_show,
        .store  = auto_poweron_store,
};

#ifndef CONFIG_PM
decl_subsys(power,NULL,NULL);

static struct attribute *g[] = {
        &auto_poweron_attr.attr,
        NULL,
};

static struct attribute_group attr_group = {
        .attrs = g,
};

static int __init pm_init(void)
{
        int error = subsystem_register(&power_subsys);
        if (!error)
                error = sysfs_create_group(&power_subsys.kset.kobj,&attr_group);
        return error;
}
core_initcall(pm_init);
#else
extern struct subsystem power_subsys;

static int __init apo_pm_init(void)
{
	return (subsys_create_file(&power_subsys, &auto_poweron_attr));
}
__initcall(apo_pm_init);
#endif
+3 −0
Original line number Original line Diff line number Diff line
@@ -33,4 +33,7 @@ static inline void setup_kexec_cpu_down_xics(void) { }
static inline void setup_kexec_cpu_down_mpic(void) { }
static inline void setup_kexec_cpu_down_mpic(void) { }
#endif
#endif


/* Poweron flag used for enabling auto ups restart */
extern unsigned long rtas_poweron_auto;

#endif /* _PSERIES_PSERIES_H */
#endif /* _PSERIES_PSERIES_H */
+29 −1
Original line number Original line Diff line number Diff line
@@ -486,6 +486,34 @@ static int pSeries_pci_probe_mode(struct pci_bus *bus)
	return PCI_PROBE_NORMAL;
	return PCI_PROBE_NORMAL;
}
}


/**
 * pSeries_power_off - tell firmware about how to power off the system.
 *
 * This function calls either the power-off rtas token in normal cases
 * or the ibm,power-off-ups token (if present & requested) in case of
 * a power failure. If power-off token is used, power on will only be
 * possible with power button press. If ibm,power-off-ups token is used
 * it will allow auto poweron after power is restored.
 */
void pSeries_power_off(void)
{
	int rc;
	int rtas_poweroff_ups_token = rtas_token("ibm,power-off-ups");

	if (rtas_flash_term_hook)
		rtas_flash_term_hook(SYS_POWER_OFF);

	if (rtas_poweron_auto == 0 ||
		rtas_poweroff_ups_token == RTAS_UNKNOWN_SERVICE) {
		rc = rtas_call(rtas_token("power-off"), 2, 1, NULL, -1, -1);
		printk(KERN_INFO "RTAS power-off returned %d\n", rc);
	} else {
		rc = rtas_call(rtas_poweroff_ups_token, 0, 1, NULL);
		printk(KERN_INFO "RTAS ibm,power-off-ups returned %d\n", rc);
	}
	for (;;);
}

define_machine(pseries) {
define_machine(pseries) {
	.name			= "pSeries",
	.name			= "pSeries",
	.probe			= pSeries_probe,
	.probe			= pSeries_probe,
@@ -496,7 +524,7 @@ define_machine(pseries) {
	.pcibios_fixup		= pSeries_final_fixup,
	.pcibios_fixup		= pSeries_final_fixup,
	.pci_probe_mode		= pSeries_pci_probe_mode,
	.pci_probe_mode		= pSeries_pci_probe_mode,
	.restart		= rtas_restart,
	.restart		= rtas_restart,
	.power_off		= rtas_power_off,
	.power_off		= pSeries_power_off,
	.halt			= rtas_halt,
	.halt			= rtas_halt,
	.panic			= rtas_os_term,
	.panic			= rtas_os_term,
	.get_boot_time		= rtas_get_boot_time,
	.get_boot_time		= rtas_get_boot_time,