1 /* 2 * PowerNV OPAL power control for graceful shutdown handling 3 * 4 * Copyright 2015 IBM Corp. 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License 8 * as published by the Free Software Foundation; either version 9 * 2 of the License, or (at your option) any later version. 10 */ 11 12 #include <linux/kernel.h> 13 #include <linux/reboot.h> 14 #include <linux/notifier.h> 15 16 #include <asm/opal.h> 17 #include <asm/machdep.h> 18 19 #define SOFT_OFF 0x00 20 #define SOFT_REBOOT 0x01 21 22 static int opal_power_control_event(struct notifier_block *nb, 23 unsigned long msg_type, void *msg) 24 { 25 struct opal_msg *power_msg = msg; 26 uint64_t type; 27 28 type = be64_to_cpu(power_msg->params[0]); 29 30 switch (type) { 31 case SOFT_REBOOT: 32 /* Fall through. The service processor is responsible for 33 * bringing the machine back up */ 34 case SOFT_OFF: 35 pr_info("OPAL: poweroff requested\n"); 36 orderly_poweroff(true); 37 break; 38 default: 39 pr_err("OPAL: power control type unexpected %016llx\n", type); 40 } 41 42 return 0; 43 } 44 45 static struct notifier_block opal_power_control_nb = { 46 .notifier_call = opal_power_control_event, 47 .next = NULL, 48 .priority = 0, 49 }; 50 51 static int __init opal_power_control_init(void) 52 { 53 int ret; 54 55 ret = opal_message_notifier_register(OPAL_MSG_SHUTDOWN, 56 &opal_power_control_nb); 57 if (ret) { 58 pr_err("%s: Can't register OPAL event notifier (%d)\n", 59 __func__, ret); 60 return ret; 61 } 62 63 return 0; 64 } 65 machine_subsys_initcall(powernv, opal_power_control_init); 66