diff options
Diffstat (limited to 'roms/skiboot/hw/ipmi/ipmi-power.c')
-rw-r--r-- | roms/skiboot/hw/ipmi/ipmi-power.c | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/roms/skiboot/hw/ipmi/ipmi-power.c b/roms/skiboot/hw/ipmi/ipmi-power.c new file mode 100644 index 000000000..8101a8524 --- /dev/null +++ b/roms/skiboot/hw/ipmi/ipmi-power.c @@ -0,0 +1,85 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* + * Power as in electricity, not POWER as in POWER + * + * Copyright 2013-2019 IBM Corp. + */ + +#include <skiboot.h> +#include <stdlib.h> +#include <ipmi.h> +#include <opal.h> +#include <timebase.h> + +static void ipmi_chassis_control_complete(struct ipmi_msg *msg) +{ + uint8_t request = msg->data[0]; + uint8_t cc = msg->cc; + + ipmi_free_msg(msg); + if (cc == IPMI_CC_NO_ERROR) + return; + + prlog(PR_INFO, "IPMI: Chassis control request failed. " + "request=0x%02x, rc=0x%02x\n", request, cc); + + if (ipmi_chassis_control(request)) { + prlog(PR_INFO, "IPMI: Failed to resend chassis control " + "request [0x%02x]\n", request); + } +} + +int ipmi_chassis_control(uint8_t request) +{ + struct ipmi_msg *msg; + + if (!ipmi_present()) + return OPAL_CLOSED; + + if (request > IPMI_CHASSIS_SOFT_SHUTDOWN) + return OPAL_PARAMETER; + + msg = ipmi_mkmsg(IPMI_DEFAULT_INTERFACE, IPMI_CHASSIS_CONTROL, + ipmi_chassis_control_complete, NULL, + &request, sizeof(request), 0); + if (!msg) + return OPAL_HARDWARE; + /* Set msg->error callback function */ + msg->error = ipmi_chassis_control_complete; + + prlog(PR_INFO, "IPMI: sending chassis control request 0x%02x\n", + request); + + return ipmi_queue_msg(msg); +} + +int ipmi_set_power_state(uint8_t system, uint8_t device) +{ + struct ipmi_msg *msg; + struct { + uint8_t system; + uint8_t device; + } power_state; + + if (!ipmi_present()) + return OPAL_CLOSED; + + power_state.system = system; + power_state.device = device; + + if (system != IPMI_PWR_NOCHANGE) + power_state.system |= 0x80; + if (device != IPMI_PWR_NOCHANGE) + power_state.device |= 0x80; + + msg = ipmi_mkmsg_simple(IPMI_SET_POWER_STATE, &power_state, + sizeof(power_state)); + + if (!msg) + return OPAL_HARDWARE; + + prlog(PR_INFO, "IPMI: setting power state: sys %02x, dev %02x\n", + power_state.system, power_state.device); + + return ipmi_queue_msg(msg); +} |