[Skiboot] [PATCH] FSP/EPOW: Add support for FSP EPOW events in OPAL

Vipin K Parashar vipin at linux.vnet.ibm.com
Thu Apr 30 15:38:01 AEST 2015


This patch adds support for FSP EPOW events in OPAL.
Below EPOW conditions are covered by this patch.
 * System running on UPS power
 * System running on UPS Power with UPS battery low.
 * High ambient tempeature
 * Critical ambient temperature
 * High internal temperature
 * Critical internal temperature
Along with these events support for EPOW reset i.e. EPOW condition
return to normal state is also added. OPAL EPOW notifications are
sent to host for each of above cases.

Signed-off-by: Vipin K Parashar <vipin at linux.vnet.ibm.com>
---
 hw/fsp/fsp-epow.c  | 366 ++++++++++++++++++++++++++---------------------------
 hw/fsp/fsp-epow.h  |  30 +++--
 include/opal-api.h |  82 +++++-------
 3 files changed, 232 insertions(+), 246 deletions(-)

diff --git a/hw/fsp/fsp-epow.c b/hw/fsp/fsp-epow.c
index eaba8bb..499d2db 100644
--- a/hw/fsp/fsp-epow.c
+++ b/hw/fsp/fsp-epow.c
@@ -1,10 +1,11 @@
-/* Copyright 2013-2014 IBM Corp.
+/*
+ * Copyright 2013-2014 IBM Corp.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  *
- * 	http://www.apache.org/licenses/LICENSE-2.0
+ *	http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -13,229 +14,220 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/*
- * Handle FSP Environmental and Power Warning (EPOW) events notification
- */
-#include <skiboot.h>
-#include <console.h>
+
+/* FSP Early Power Off Warning (EPOW) support */
+
 #include <fsp.h>
 #include <device.h>
-#include <stdio.h>
-#include <spcn.h>
-#include <opal.h>
+#include <lock.h>
 #include <opal-msg.h>
+#include <opal-api.h>
 
 #include "fsp-epow.h"
 
-#define PREFIX "FSPEPOW: "
+#define PREFIX "FSP-EPOW: "
+
+#define EPOW_EVENT_DETECTED	1
 
 /*
  * System EPOW status
  *
- * This value is exported to the host. Each individual element in this array
- * [0..(OPAL_SYSEPOW_MAX -1)] contains detailed status (in it's bit positions)
- * corresponding to a particular defined EPOW sub class. For example.
- *
- * epow_status[OPAL_SYSEPOW_POWER] will reflect whether the system has one or
- * more of power subsystem specific EPOW events like OPAL_SYSPOWER_UPS,
- * OPAL_SYSPOWER_CHNG, OPAL_SYSPOWER_FAIL or OPAL_SYSPOWER_INCL.
+ * This value is exported to the host. Each individual element in this
+ * array [0...(OPAL_MAX_EPOW_CLASSES-1)] contains bitwise EPOW event info
+ * corresponding to particular defined EPOW sub class. For example.
+ * opal_epow_status[OPAL_EPOW_POWER] will reflect power related EPOW events.
  */
-static int16_t epow_status[OPAL_SYSEPOW_MAX];
+static u32 opal_epow_status[OPAL_MAX_EPOW_CLASSES];
 
 /* EPOW lock */
 static struct lock epow_lock = LOCK_UNLOCKED;
 
-/* Process FSP sent SPCN based information */
-static void epow_process_base_event(u8 *epow)
-{
+/* Utilty Failure (UF) bit status */
+static u8 utility_fail_mask;
 
-	epow_status[OPAL_SYSEPOW_POWER] &= ~(OPAL_SYSPOWER_CHNG |
-				OPAL_SYSPOWER_FAIL | OPAL_SYSPOWER_INCL);
-	/*
-	 * FIXME: As of now, SPCN_FAULT_LOG event is not being used
-	 * as it does not map to any generic defined OPAL EPOW event.
-	 */
-	if (epow[3] & SPCN_CNF_CHNG) {
-		/*
-		 * The frequency of the SPCN_CNF_CHNG message is very
-		 * high on POWER7 and POWER8 systems which will fill
-		 * up the Sapphire log buffer. SPCN configuration
-		 * change does not take down the system, hence the
-		 * logging of these type of messages can be avoided to
-		 * save precious log buffer space.
-		 */
-		epow_status[OPAL_SYSEPOW_POWER] |= OPAL_SYSPOWER_CHNG;
-	}
+/* Battery Low (BL) bit status */
+static u8 battery_low_mask;
 
-	if (epow[3] & SPCN_POWR_FAIL) {
-		prlog(PR_TRACE, PREFIX "FSP message with SPCN_POWR_FAIL\n");
-		epow_status[OPAL_SYSEPOW_POWER] |= OPAL_SYSPOWER_FAIL;
-	}
+/* Process EPOW event notification */
+static int process_epow_event(struct fsp_msg *msg)
+{
+	int rc = -1;
+	int unknown_epow = 0, epow_reason;
+	u8 ups_status;
+	bool new_epow_event = false;
 
-	if (epow[3] & SPCN_INCL_POWR) {
-		prlog(PR_TRACE, PREFIX "FSP message with SPCN_INCL_POWR\n");
-		epow_status[OPAL_SYSEPOW_POWER] |= OPAL_SYSPOWER_INCL;
-	}
-}
+	prlog(PR_DEBUG, PREFIX "UPS byte = 0x%x, SPCN byte = 0x%x\n",
+	msg->data.bytes[1], msg->data.bytes[2]);
 
-/* Process FSP sent EPOW based information */
-static void epow_process_ex1_event(u8 *epow)
-{
-	epow_status[OPAL_SYSEPOW_POWER] &= ~OPAL_SYSPOWER_UPS;
-	epow_status[OPAL_SYSEPOW_TEMP] &= ~(OPAL_SYSTEMP_AMB | OPAL_SYSTEMP_INT);
+	/* UPS status bits information. */
+	ups_status = msg->data.bytes[1];
 
-	if (epow[4] == EPOW_ON_UPS) {
-		prlog(PR_TRACE, PREFIX "FSP message with EPOW_ON_UPS\n");
-		epow_status[OPAL_SYSEPOW_POWER] |= OPAL_SYSPOWER_UPS;
+	/*
+	* Check if there is any change in UF and BL bits,
+	* signifying new EPOW event.
+	*/
+	lock(&epow_lock);
+	if (utility_fail_mask != (ups_status & UPS_UTILITY_FAIL)) {
+		/* Update new utilty fail mask */
+		utility_fail_mask = (ups_status & UPS_UTILITY_FAIL);
+		new_epow_event = true;
 	}
 
-	if (epow[4] == EPOW_TMP_AMB) {
-		prlog(PR_TRACE, PREFIX "FSP message with EPOW_TMP_AMB\n");
-		epow_status[OPAL_SYSEPOW_TEMP] |= OPAL_SYSTEMP_AMB;
+	/*
+	* With non-zero utility fail mask, check if there is any change in
+	* battery low mask value . With zero utility fail mask value, battery
+	* low mask change doesn't trigger EPOW event.
+	*/
+	if (utility_fail_mask) {
+		if (battery_low_mask != (ups_status & UPS_BATTERY_LOW)) {
+			/* Update new battery low mask */
+			battery_low_mask = (ups_status & UPS_BATTERY_LOW);
+			new_epow_event = true;
+		}
 	}
 
-	if (epow[4] == EPOW_TMP_INT) {
-		prlog(PR_TRACE, PREFIX "FSP message with EPOW_TMP_INT\n");
-		epow_status[OPAL_SYSEPOW_TEMP] |= OPAL_SYSTEMP_INT;
+	prlog(PR_DEBUG, PREFIX "UF Mask = 0x%x, BL Mask = 0x%x. "
+			"New EPOW event = %d\n", utility_fail_mask,
+			battery_low_mask, new_epow_event);
+
+	if (new_epow_event == false) {
+		unlock(&epow_lock);
+		return rc;
 	}
-}
 
-/* Update the system EPOW status */
-static void fsp_epow_update(u8 *epow, int epow_type)
-{
-	int16_t old_epow_status[OPAL_SYSEPOW_MAX];
-	bool epow_changed = false;
-	int rc;
+	/* Collect EPOW reason code information */
+	epow_reason = msg->data.bytes[4];
 
-	lock(&epow_lock);
+	/* Proceed with new EPOW event processing */
+	switch (epow_reason) {
+	case EPOW_NONE:
+		if (!utility_fail_mask && !battery_low_mask) {
+			memset(opal_epow_status, 0,
+			sizeof(opal_epow_status[0] * OPAL_MAX_EPOW_CLASSES));
+			prlog(PR_INFO,
+				PREFIX "EPOW condition returned to normal\n");
+		} else
+			unknown_epow = 1;
+		break;
 
-	/* Copy over and clear system EPOW status */
-	memcpy(old_epow_status, epow_status, sizeof(old_epow_status));
-	switch(epow_type) {
-	case EPOW_NORMAL:
-		epow_process_base_event(epow);
-		/* FIXME: IPL mode information present but not used */
+	case EPOW_ON_UPS:
+		if (utility_fail_mask && !battery_low_mask) {
+			opal_epow_status[OPAL_EPOW_POWER] = OPAL_EPOW_POWER_UPS;
+			prlog(PR_INFO,
+				PREFIX "EPOW due to system on UPS power\n");
+		} else if (utility_fail_mask && battery_low_mask) {
+			opal_epow_status[OPAL_EPOW_POWER] =
+				OPAL_EPOW_POWER_UPS_LOW;
+			prlog(PR_INFO,
+				PREFIX "EPOW due to system on UPS power "
+				"with UPS battery low.\n");
+		} else
+			unknown_epow = 1;
 		break;
-	case EPOW_EX1:
-		epow_process_base_event(epow);
-		epow_process_ex1_event(epow);
-		/* FIXME: IPL mode information present but not used */
-		/* FIXME: Key position information present but not used */
+
+	case EPOW_AMB_TEMP:
+		if (utility_fail_mask && !battery_low_mask)  {
+			opal_epow_status[OPAL_EPOW_TEMP] =
+				OPAL_EPOW_TEMP_HIGH_AMB;
+			prlog(PR_INFO,
+				PREFIX "EPOW due to high ambient temp\n");
+		} else if (utility_fail_mask && battery_low_mask) {
+			opal_epow_status[OPAL_EPOW_TEMP] =
+				OPAL_EPOW_TEMP_CRIT_AMB;
+			prlog(PR_INFO,
+				PREFIX "EPOW due to critical ambient temp\n");
+		} else
+			unknown_epow = 1;
 		break;
-	case EPOW_EX2:
-		/*FIXME: IPL mode information present but not used */
-		/*FIXME: Key position information present but not used */
+
+	case EPOW_INT_TEMP:
+		if (utility_fail_mask && !battery_low_mask) {
+			opal_epow_status[OPAL_EPOW_TEMP] =
+				OPAL_EPOW_TEMP_HIGH_INT;
+			prlog(PR_INFO,
+				PREFIX "EPOW due to high internal temp\n");
+		 } else if (utility_fail_mask && battery_low_mask) {
+			opal_epow_status[OPAL_EPOW_TEMP] =
+				OPAL_EPOW_TEMP_CRIT_INT;
+			prlog(PR_INFO,
+				PREFIX "EPOW due to critical internal temp\n");
+		} else
+			unknown_epow = 1;
 		break;
+
 	default:
-		prlog(PR_WARNING, PREFIX "Unknown EPOW event notification\n");
-		break;
+		unknown_epow = 1;
 	}
 	unlock(&epow_lock);
 
-	if (memcmp(epow_status, old_epow_status, sizeof(epow_status)))
-		epow_changed = true;
+	prlog(PR_DEBUG, PREFIX "Supported EPOW classes = %d. "
+		"EPOW Status = 0x%x 0x%x 0x%x\n", OPAL_MAX_EPOW_CLASSES,
+		opal_epow_status[0], opal_epow_status[1], opal_epow_status[2]);
 
-	/* Send OPAL message notification */
-	if (epow_changed) {
-		rc = opal_queue_msg(OPAL_MSG_EPOW, NULL, NULL);
-		if (rc) {
-			prlog(PR_ERR, PREFIX "OPAL EPOW message queuing failed\n");
-			return;
-		}
+	if (unknown_epow) {
+		prerror("Unknown EPOW. UF Mask = 0x%x, BL Mask = 0x%x, "
+			"Reason = %d\n", utility_fail_mask,
+				battery_low_mask, epow_reason);
+		return rc;
 	}
+
+	return EPOW_EVENT_DETECTED;
+}
+
+/*
+ * Notify host about EPOW event. Host should make a OPAL call
+ * subsequently to obtain EPOW event information.
+ */
+static void notify_epow_event(void)
+{
+	int rc;
+
+	/* Send OPAL message notification */
+	rc = opal_queue_msg(OPAL_MSG_EPOW, NULL, NULL);
+	if (rc)
+		prerror("OPAL message queuing failed for EPOW event. "
+				"rc = %d\n", rc);
+	else
+		prlog(PR_INFO, PREFIX "Notified host about EPOW event.\n");
 }
 
-/* Process captured EPOW event notification */
-static void fsp_process_epow(struct fsp_msg *msg, int epow_type)
+/* Process panel status notification */
+static void process_panel_status(struct fsp_msg *msg, int panel_type)
 {
-	struct fsp_msg *resp;
-	u8 epow[8];
+	int rc;
 
-	/* Basic EPOW signature */
+	/* Match panel status notification signature */
 	if (msg->data.bytes[0] != 0xF2) {
-		prlog(PR_ERR, PREFIX "Signature mismatch\n");
+		prerror("Signature mismatch\n");
 		return;
 	}
 
-	/* Common to all EPOW event types */
-	epow[0] = msg->data.bytes[0];
-	epow[1] = msg->data.bytes[1];
-	epow[2] = msg->data.bytes[2];
-	epow[3] = msg->data.bytes[3];
-
-	/*
-	 * After receiving the FSP async message, HV needs to
-	 * ask for the detailed panel status through corresponding
-	 * mbox command. HV need not use the received details status
-	 * as it does not have any thing more or new than what came
-	 * along with the original FSP async message. But requesting
-	 * for the detailed panel status exclussively is necessary as
-	 * it forms a kind of handshaking with the FSP. Without this
-	 * step, FSP wont be sending any new panel status messages.
-	 */
-	switch(epow_type) {
-	case EPOW_NORMAL:
-		resp = fsp_mkmsg(FSP_CMD_STATUS_REQ, 0);
-		if (resp == NULL) {
-			prerror(PREFIX "%s : Message allocation failed\n",
-				__func__);
-			break;
-		}
-		if (fsp_queue_msg(resp, fsp_freemsg)) {
-			fsp_freemsg(resp);
-			prerror(PREFIX "%s : Failed to queue response "
-				"message\n", __func__);
-		}
-		break;
-	case EPOW_EX1:
-		/* EPOW_EX1 specific extra event data */
-		epow[4] = msg->data.bytes[4];
-		resp = fsp_mkmsg(FSP_CMD_STATUS_EX1_REQ, 0);
-		if (resp == NULL) {
-			prerror(PREFIX "%s : Message allocation failed\n",
-				__func__);
-			break;
-		}
-		if (fsp_queue_msg(resp, fsp_freemsg)) {
-			fsp_freemsg(resp);
-			prerror(PREFIX "%s : Failed to queue response "
-				"message\n", __func__);
-		}
-		break;
-	case EPOW_EX2:
-		resp = fsp_mkmsg(FSP_CMD_STATUS_EX2_REQ, 0);
-		if (resp == NULL) {
-			prerror(PREFIX "%s : Message allocation failed\n",
-				__func__);
-			break;
-		}
-		if (fsp_queue_msg(resp, fsp_freemsg)) {
-			fsp_freemsg(resp);
-			prerror(PREFIX "%s : Failed to queue response "
-				"message\n", __func__);
-		}
-		break;
-	default:
-		prlog(PR_WARNING, PREFIX "Unknown EPOW event notification\n");
+	/* EPOW event information is encoded in extended panel 1 status */
+	if (panel_type != PANEL_EX1)
 		return;
-	}
-	fsp_epow_update(epow, epow_type);
+
+	/* Process EPOW event information. */
+	rc = process_epow_event(msg);
+
+	/* Notify host about new EPOW event */
+	if (rc == EPOW_EVENT_DETECTED)
+		notify_epow_event();
 }
 
 /*
  * EPOW OPAL interface
  *
  * The host requests for the system EPOW status through this
- * OPAl call, where it passes a buffer with a give length.
- * Sapphire fills the buffer with updated system EPOW status
- * and then updates the length variable back to reflect the
- * number of EPOW sub classes it has updated the buffer with.
+ * OPAl call. Host passes an buffer address as first argument
+ * while second argument contains number of EPOW classes known
+ * by it. OPAL populates passed buffer with its EPOW status
+ * and updates variable having number of classes with number of
+ * EPOW classes for which it has returned status.
  */
-static int64_t fsp_opal_get_epow_status(int16_t *out_epow,
-						int16_t *length)
+static int32_t opal_get_epow_status(u32 *epow_status,
+						int32_t *num_epow_classes)
 {
 	int i;
-	int n_epow_class;
 
 	/*
 	 * There can be situations where the host and the Sapphire versions
@@ -255,16 +247,14 @@ static int64_t fsp_opal_get_epow_status(int16_t *out_epow,
 	 * Sapphire sends out EPOW status for sub classes host knows about
 	 * and can interpret correctly.
 	 */
-	if (*length >= OPAL_SYSEPOW_MAX) {
-		n_epow_class = OPAL_SYSEPOW_MAX;
-		*length = OPAL_SYSEPOW_MAX;
-	} else {
-		n_epow_class = *length;
-	}
+	if (*num_epow_classes > OPAL_MAX_EPOW_CLASSES)
+		*num_epow_classes = OPAL_MAX_EPOW_CLASSES;
 
-	/* Transfer EPOW Status */
-	for (i = 0; i < n_epow_class; i++)
-		out_epow[i] = epow_status[i];
+	/* Copy EPOW Status */
+	lock(&epow_lock);
+	for (i = 0; i < *num_epow_classes; i++)
+		epow_status[i] = opal_epow_status[i];
+	unlock(&epow_lock);
 
 	return OPAL_SUCCESS;
 }
@@ -274,13 +264,13 @@ static bool fsp_epow_message(u32 cmd_sub_mod, struct fsp_msg *msg)
 {
 	switch(cmd_sub_mod) {
 	case FSP_CMD_PANELSTATUS:
-		fsp_process_epow(msg, EPOW_NORMAL);
+		process_panel_status(msg, PANEL_NORMAL);
 		return true;
 	case FSP_CMD_PANELSTATUS_EX1:
-		fsp_process_epow(msg, EPOW_EX1);
+		process_panel_status(msg, PANEL_EX1);
 		return true;
 	case FSP_CMD_PANELSTATUS_EX2:
-		fsp_process_epow(msg, EPOW_EX2);
+		process_panel_status(msg, PANEL_EX2);
 		return true;
 	}
 	return false;
@@ -294,10 +284,16 @@ void fsp_epow_init(void)
 {
 	struct dt_node *np;
 
+	/* Register FSP EPOW notifications */
 	fsp_register_client(&fsp_epow_client, FSP_MCLASS_SERVICE);
-	opal_register(OPAL_GET_EPOW_STATUS, fsp_opal_get_epow_status, 2);
+
+	/* Register host OPAL EPOW interface */
+	opal_register(OPAL_GET_EPOW_STATUS, opal_get_epow_status, 2);
+
+	/* Device tree node for EPOW events */
 	np = dt_new(opal_node, "epow");
-	dt_add_property_strings(np, "compatible", "ibm,opal-v3-epow");
+	dt_add_property_strings(np, "compatible", "ibm,opal-epow");
 	dt_add_property_strings(np, "epow-classes", "power", "temperature", "cooling");
-	prlog(PR_TRACE, PREFIX "FSP EPOW support initialized\n");
+
+	prlog(PR_INFO, PREFIX "FSP EPOW support initialized\n");
 }
diff --git a/hw/fsp/fsp-epow.h b/hw/fsp/fsp-epow.h
index 24a0ae9..cab9fcf 100644
--- a/hw/fsp/fsp-epow.h
+++ b/hw/fsp/fsp-epow.h
@@ -1,10 +1,11 @@
-/* Copyright 2013-2014 IBM Corp.
+/*
+ * Copyright 2013-2014 IBM Corp.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  *
- * 	http://www.apache.org/licenses/LICENSE-2.0
+ *	http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,17 +15,15 @@
  * limitations under the License.
  */
 
-/*
- * Handle FSP EPOW event notifications
- */
+/* FSP EPOW (Early Power Off Warning) support */
 
 #ifndef __FSP_EPOW_H
 #define __FSP_EPOW_H
 
-/* FSP based EPOW event notifications */
-#define EPOW_NORMAL	0x00	/* panel status normal */
-#define EPOW_EX1	0x01	/* panel status extended 1 */
-#define EPOW_EX2	0x02	/* Panel status extended 2 */
+/* FSP Panel Status type */
+#define PANEL_NORMAL	0	/* Normal Panel */
+#define PANEL_EX1	1	/* Extended Panel 1 */
+#define PANEL_EX2	2	/* Extended Panel 2 */
 
 /* SPCN notifications */
 #define SPCN_CNF_CHNG	0x08	/* SPCN configuration change */
@@ -32,9 +31,16 @@
 #define SPCN_POWR_FAIL	0x02	/* SPCN impending power failure */
 #define SPCN_INCL_POWR	0x01	/* SPCN incomplete power */
 
-/* EPOW reason code notifications */
+/* EPOW reason codes */
+#define EPOW_NONE	0	/* EPOW normal/reset */
 #define EPOW_ON_UPS	1	/* System on UPS */
-#define EPOW_TMP_AMB	2	/* Over ambient temperature */
-#define EPOW_TMP_INT	3	/* Over internal temperature */
+#define EPOW_AMB_TEMP	2	/* Over ambient temperature */
+#define EPOW_INT_TEMP	3	/* Over internal temperature */
+
+/* UPS bits mask used in EPOW notifications */
+#define UPS_PRESENT		0x80    /* UPS present */
+#define UPS_UTILITY_FAIL	0x40    /* UPS utility fail */
+#define UPS_BYPASED		0x20    /* UPS bypassed */
+#define UPS_BATTERY_LOW		0x10    /* UPS battery low */
 
 #endif
diff --git a/include/opal-api.h b/include/opal-api.h
index 1698311..12e427c 100644
--- a/include/opal-api.h
+++ b/include/opal-api.h
@@ -1,10 +1,11 @@
-/* Copyright 2013-2014 IBM Corp.
+/*
+ * Copyright 2013-2014 IBM Corp.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  *
- * 	http://www.apache.org/licenses/LICENSE-2.0
+ *	http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -384,13 +385,6 @@ enum OpalSlotLedState {
 	OPAL_SLOT_LED_STATE_ON = 1	/* LED is ON */
 };
 
-enum OpalEpowStatus {
-	OPAL_EPOW_NONE = 0,
-	OPAL_EPOW_UPS = 1,
-	OPAL_EPOW_OVER_AMBIENT_TEMP = 2,
-	OPAL_EPOW_OVER_INTERNAL_TEMP = 3
-};
-
 enum OpalCheckTokenStatus {
 	OPAL_TOKEN_ABSENT = 0,
 	OPAL_TOKEN_PRESENT = 1
@@ -444,46 +438,6 @@ struct opal_ipmi_msg {
 	uint8_t data[];
 };
 
-/*
- * EPOW status sharing (OPAL and the host)
- *
- * The host will pass on OPAL, a buffer of length OPAL_SYSEPOW_MAX
- * with individual elements being 16 bits wide to fetch the system
- * wide EPOW status. Each element in the buffer will contain the
- * EPOW status in it's bit representation for a particular EPOW sub
- * class as defiend here. So multiple detailed EPOW status bits
- * specific for any sub class can be represented in a single buffer
- * element as it's bit representation.
- */
-
-/* System EPOW type */
-enum OpalSysEpow {
-	OPAL_SYSEPOW_POWER	= 0,	/* Power EPOW */
-	OPAL_SYSEPOW_TEMP	= 1,	/* Temperature EPOW */
-	OPAL_SYSEPOW_COOLING	= 2,	/* Cooling EPOW */
-	OPAL_SYSEPOW_MAX	= 3,	/* Max EPOW categories */
-};
-
-/* Power EPOW */
-enum OpalSysPower {
-	OPAL_SYSPOWER_UPS	= 0x0001, /* System on UPS power */
-	OPAL_SYSPOWER_CHNG	= 0x0002, /* System power configuration change */
-	OPAL_SYSPOWER_FAIL	= 0x0004, /* System impending power failure */
-	OPAL_SYSPOWER_INCL	= 0x0008, /* System incomplete power */
-};
-
-/* Temperature EPOW */
-enum OpalSysTemp {
-	OPAL_SYSTEMP_AMB	= 0x0001, /* System over ambient temperature */
-	OPAL_SYSTEMP_INT	= 0x0002, /* System over internal temperature */
-	OPAL_SYSTEMP_HMD	= 0x0004, /* System over ambient humidity */
-};
-
-/* Cooling EPOW */
-enum OpalSysCooling {
-	OPAL_SYSCOOL_INSF	= 0x0001, /* System insufficient cooling */
-};
-
 /* FSP memory errors handling */
 enum OpalMemErr_Version {
 	OpalMemErr_V1 = 1,
@@ -941,6 +895,36 @@ struct opal_i2c_request {
 	__be64 buffer_ra;		/* Buffer real address */
 };
 
+/*
+ * EPOW status sharing (OPAL and the host)
+ *
+ * The host will pass on OPAL, a buffer of length OPAL_EPOW_MAX_CLASSES
+ * to fetch system wide EPOW status. Each element in the returned buffer
+ * will contain bitwise EPOW status for each EPOW sub class.
+ */
+
+/* EPOW types */
+enum OpalEpow {
+	OPAL_EPOW_POWER		= 0,	/* Power EPOW */
+	OPAL_EPOW_TEMP		= 1,	/* Temperature EPOW */
+	OPAL_EPOW_COOLING	= 2,	/* Cooling EPOW */
+	OPAL_MAX_EPOW_CLASSES	= 3,	/* Max EPOW categories */
+};
+
+/* Power EPOW events */
+enum OpalEpowPower {
+	OPAL_EPOW_POWER_UPS	= 0x1, /* System on UPS power */
+	OPAL_EPOW_POWER_UPS_LOW	= 0x2, /* System on UPS power with low battery*/
+};
+
+/* Temperature EPOW events */
+enum OpalEpowTemp {
+	OPAL_EPOW_TEMP_HIGH_AMB	= 0x1, /* High ambient temperature */
+	OPAL_EPOW_TEMP_CRIT_AMB	= 0x2, /* Critical ambient temperature */
+	OPAL_EPOW_TEMP_HIGH_INT	= 0x4, /* High internal temperature */
+	OPAL_EPOW_TEMP_CRIT_INT	= 0x8, /* Critical internal temperature */
+};
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* __OPAL_API_H */
-- 
1.9.3



More information about the Skiboot mailing list