aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hdata/hdata.h1
-rw-r--r--hdata/slca.c79
-rw-r--r--hdata/spira.c3
-rw-r--r--hdata/spira.h1
4 files changed, 84 insertions, 0 deletions
diff --git a/hdata/hdata.h b/hdata/hdata.h
index 79cc576..567927c 100644
--- a/hdata/hdata.h
+++ b/hdata/hdata.h
@@ -43,6 +43,7 @@ extern const struct slca_entry *slca_get_entry(uint16_t slca_index);
extern const char *slca_get_vpd_name(uint16_t slca_index);
extern const char *slca_get_loc_code_index(uint16_t slca_index);
extern void slca_vpd_add_loc_code(struct dt_node *node, uint16_t slca_index);
+extern void slca_dt_add_sai_node(void);
extern bool hservices_from_hdat(const void *fdt, size_t size);
diff --git a/hdata/slca.c b/hdata/slca.c
index aaa5fc6..3130d5b 100644
--- a/hdata/slca.c
+++ b/hdata/slca.c
@@ -16,6 +16,9 @@
#include <device.h>
+#include <include/opal-internal.h>
+#include <fsp-leds.h>
+
#include "spira.h"
#include "hdata.h"
@@ -89,3 +92,79 @@ void slca_vpd_add_loc_code(struct dt_node *node, uint16_t slca_index)
strncpy(loc_code, fru_loc_code, LOC_CODE_SIZE - 1);
dt_add_property(node, "ibm,loc-code", loc_code, strlen(loc_code) + 1);
}
+
+/*
+ * Get System Attention Indicator SLCA entry
+ */
+static const struct slca_entry *slca_get_sai_entry(void)
+{
+ int count;
+ unsigned int i;
+ struct HDIF_common_hdr *slca_hdr;
+
+ slca_hdr = get_hdif(&spira.ntuples.slca, SLCA_HDIF_SIG);
+ if (!slca_hdr) {
+ prerror("SLCA Invalid\n");
+ return NULL;
+ }
+
+ count = HDIF_get_iarray_size(slca_hdr, SLCA_IDATA_ARRAY);
+ if (count < 0) {
+ prerror("SLCA: Can't find SLCA array size!\n");
+ return NULL;
+ }
+
+ for (i = 0; i < count; i++) {
+ const struct slca_entry *s_entry;
+ unsigned int entry_sz;
+
+ s_entry = HDIF_get_iarray_item(slca_hdr, SLCA_IDATA_ARRAY,
+ i, &entry_sz);
+ if (s_entry &&
+ VPD_ID(s_entry->fru_id[0],
+ s_entry->fru_id[1]) == SLCA_SAI_INDICATOR_ID) {
+ prlog(PR_TRACE, "SLCA: SAI index: 0x%x\n",
+ s_entry->my_index);
+ prlog(PR_TRACE, "SLCA: SAI location code: %s\n",
+ s_entry->loc_code);
+ return s_entry;
+ }
+ }
+
+ return NULL;
+}
+
+/*
+ * SLCA structure contains System Attention Indicator location
+ * code (FRU ID = SA). Add this information to device tree
+ * (under '/ibm,opal/led').
+ */
+void slca_dt_add_sai_node(void)
+{
+ const struct slca_entry *s_entry;
+ struct dt_node *led_node, *sai_node;
+
+ s_entry = slca_get_sai_entry();
+ if (!s_entry)
+ return;
+
+ /* Create /ibm,opal node, if its not created already */
+ if (!opal_node)
+ return;
+
+ /* Crete LED parent node */
+ led_node = dt_find_by_path(opal_node, DT_PROPERTY_LED_NODE);
+ if (!led_node)
+ return;
+
+ if (s_entry->loc_code_len == 0 ||
+ s_entry->loc_code_len > LOC_CODE_SIZE)
+ return;
+
+ /* Create SAI node */
+ sai_node = dt_new(led_node, s_entry->loc_code);
+ assert(sai_node);
+
+ dt_add_property_string(sai_node,
+ DT_PROPERTY_LED_TYPES, LED_TYPE_ATTENTION);
+}
diff --git a/hdata/spira.c b/hdata/spira.c
index d29e1dc..f7b42d8 100644
--- a/hdata/spira.c
+++ b/hdata/spira.c
@@ -1026,5 +1026,8 @@ void parse_hdat(bool is_opal, uint32_t master_cpu)
/* Host services information. */
hostservices_parse();
+ /* Parse System Attention Indicator inforamtion */
+ slca_dt_add_sai_node();
+
prlog(PR_INFO, "Parsing HDAT...done\n");
}
diff --git a/hdata/spira.h b/hdata/spira.h
index e98edbd..0916fe3 100644
--- a/hdata/spira.h
+++ b/hdata/spira.h
@@ -611,6 +611,7 @@ struct slca_entry {
uint8_t fru_id[2]; /* ASCII VPD ID */
#define SLCA_ROOT_VPD_ID VPD_ID('V','V')
#define SLCA_SYSTEM_VPD_ID VPD_ID('S','V')
+#define SLCA_SAI_INDICATOR_ID VPD_ID('S','A')
__be16 parent_index; /* Parent entry index */
uint8_t flags;
#define SLCA_FLAG_NON_FUNCTIONAL 0x02 /* For redundant entries */