diff options
-rw-r--r-- | hdata/hdata.h | 1 | ||||
-rw-r--r-- | hdata/slca.c | 79 | ||||
-rw-r--r-- | hdata/spira.c | 3 | ||||
-rw-r--r-- | hdata/spira.h | 1 |
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 */ |