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

Commit 7f43e71e authored by Joel Stanley's avatar Joel Stanley Committed by Michael Ellerman
Browse files

powerpc/powernv: Add OPAL soft-poweroff routine



Register a notifier for a OPAL message indicating that the machine
should prepare itself for a graceful power off.

OPAL will tell us if the power off is a reboot or shutdown, but for now
we perform the same orderly_poweroff action.

Signed-off-by: default avatarJoel Stanley <joel@jms.id.au>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
parent a604c96e
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -304,7 +304,7 @@ enum OpalMessageType {
					 */
	OPAL_MSG_MEM_ERR,
	OPAL_MSG_EPOW,
	OPAL_MSG_SHUTDOWN,
	OPAL_MSG_SHUTDOWN,		/* params[0] = 1 reboot, 0 shutdown */
	OPAL_MSG_HMI_EVT,
	OPAL_MSG_TYPE_MAX,
};
+1 −1
Original line number Diff line number Diff line
obj-y			+= setup.o opal-wrappers.o opal.o opal-async.o
obj-y			+= opal-rtc.o opal-nvram.o opal-lpc.o opal-flash.o
obj-y			+= rng.o opal-elog.o opal-dump.o opal-sysparam.o opal-sensor.o
obj-y			+= opal-msglog.o opal-hmi.o
obj-y			+= opal-msglog.o opal-hmi.o opal-power.o

obj-$(CONFIG_SMP)	+= smp.o subcore.o subcore-asm.o
obj-$(CONFIG_PCI)	+= pci.o pci-p5ioc2.o pci-ioda.o
+65 −0
Original line number Diff line number Diff line
/*
 * PowerNV OPAL power control for graceful shutdown handling
 *
 * Copyright 2015 IBM Corp.
 *
 * 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; either version
 * 2 of the License, or (at your option) any later version.
 */

#include <linux/kernel.h>
#include <linux/reboot.h>
#include <linux/notifier.h>

#include <asm/opal.h>
#include <asm/machdep.h>

#define SOFT_OFF 0x00
#define SOFT_REBOOT 0x01

static int opal_power_control_event(struct notifier_block *nb,
				    unsigned long msg_type, void *msg)
{
	struct opal_msg *power_msg = msg;
	uint64_t type;

	type = be64_to_cpu(power_msg->params[0]);

	switch (type) {
	case SOFT_REBOOT:
		/* Fall through. The service processor is responsible for
		 * bringing the machine back up */
	case SOFT_OFF:
		pr_info("OPAL: poweroff requested\n");
		orderly_poweroff(true);
		break;
	default:
		pr_err("OPAL: power control type unexpected %016llx\n", type);
	}

	return 0;
}

static struct notifier_block opal_power_control_nb = {
	.notifier_call	= opal_power_control_event,
	.next		= NULL,
	.priority	= 0,
};

static int __init opal_power_control_init(void)
{
	int ret;

	ret = opal_message_notifier_register(OPAL_MSG_SHUTDOWN,
					     &opal_power_control_nb);
	if (ret) {
		pr_err("%s: Can't register OPAL event notifier (%d)\n",
				__func__, ret);
		return ret;
	}

	return 0;
}
machine_subsys_initcall(powernv, opal_power_control_init);