Branch data Line data Source code
1 : : // SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
2 : : /* Copyright 2013-2015 IBM Corp. */
3 : :
4 : : #include <device.h>
5 : : #include <include/opal-internal.h>
6 : : #include <fsp-leds.h>
7 : :
8 : : #include "spira.h"
9 : : #include "hdata.h"
10 : :
11 : 145 : const struct slca_entry *slca_get_entry(uint16_t slca_index)
12 : : {
13 : : struct HDIF_common_hdr *slca_hdr;
14 : : int count;
15 : :
16 : 145 : slca_hdr = get_hdif(&spiras->ntuples.slca, SLCA_HDIF_SIG);
17 : 145 : if (!slca_hdr) {
18 : 0 : prerror("SLCA Invalid\n");
19 : 0 : return NULL;
20 : : }
21 : :
22 : 145 : count = HDIF_get_iarray_size(slca_hdr, SLCA_IDATA_ARRAY);
23 : 145 : if (count < 0) {
24 : 0 : prerror("SLCA: Can't find SLCA array size!\n");
25 : 0 : return NULL;
26 : : }
27 : :
28 : 145 : if (slca_index < count) {
29 : : const struct slca_entry *s_entry;
30 : : unsigned int entry_sz;
31 : 145 : s_entry = HDIF_get_iarray_item(slca_hdr, SLCA_IDATA_ARRAY,
32 : : slca_index, &entry_sz);
33 : :
34 : 145 : if (s_entry && entry_sz >= sizeof(*s_entry))
35 : 145 : return s_entry;
36 : : } else
37 : 0 : prlog(PR_NOTICE,
38 : : "SLCA: Can't find slca_entry for index %d\n", slca_index);
39 : 0 : return NULL;
40 : : }
41 : :
42 : 0 : const char *slca_get_vpd_name(uint16_t slca_index)
43 : : {
44 : : const struct slca_entry *s_entry;
45 : :
46 : 0 : s_entry = slca_get_entry(slca_index);
47 : 0 : if (s_entry)
48 : 0 : return (const char *)s_entry->fru_id;
49 : : else
50 : 0 : prlog(PR_NOTICE,
51 : : "SLCA: Can't find fru_id for index %d\n", slca_index);
52 : 0 : return NULL;
53 : : }
54 : :
55 : 37 : const char *slca_get_loc_code_index(uint16_t slca_index)
56 : : {
57 : : const struct slca_entry *s_entry;
58 : :
59 : 37 : s_entry = slca_get_entry(slca_index);
60 : 37 : if (s_entry)
61 : 37 : return s_entry->loc_code;
62 : : else
63 : 0 : prlog(PR_NOTICE, "SLCA: Entry %d bad idata\n", slca_index);
64 : :
65 : 0 : return NULL;
66 : : }
67 : :
68 : 32 : void slca_vpd_add_loc_code(struct dt_node *node, uint16_t slca_index)
69 : : {
70 : : const char *fru_loc_code;
71 : : char loc_code[LOC_CODE_SIZE];
72 : :
73 : 32 : memset(loc_code, 0, sizeof(loc_code));
74 : 32 : fru_loc_code = slca_get_loc_code_index(slca_index);
75 : 32 : if (!fru_loc_code)
76 : 0 : return;
77 : :
78 : 32 : strncpy(loc_code, fru_loc_code, LOC_CODE_SIZE - 1);
79 : 32 : dt_add_property(node, "ibm,loc-code", loc_code, strlen(loc_code) + 1);
80 : : }
81 : :
82 : : /*
83 : : * Get System Attention Indicator SLCA entry
84 : : */
85 : 1 : static const struct slca_entry *slca_get_sai_entry(void)
86 : : {
87 : : int count;
88 : : unsigned int i;
89 : : struct HDIF_common_hdr *slca_hdr;
90 : 1 : uint16_t sai_fru_id = SLCA_SAI_INDICATOR_ID;
91 : :
92 : 1 : slca_hdr = get_hdif(&spiras->ntuples.slca, SLCA_HDIF_SIG);
93 : 1 : if (!slca_hdr) {
94 : 0 : prerror("SLCA Invalid\n");
95 : 0 : return NULL;
96 : : }
97 : :
98 : 1 : count = HDIF_get_iarray_size(slca_hdr, SLCA_IDATA_ARRAY);
99 : 1 : if (count < 0) {
100 : 0 : prerror("SLCA: Can't find SLCA array size!\n");
101 : 0 : return NULL;
102 : : }
103 : :
104 : 1 : if (proc_gen >= proc_gen_p9 && dt_find_by_path(dt_root, "fsps"))
105 : 0 : sai_fru_id = SLCA_SYSTEM_VPD_ID;
106 : :
107 : 11 : for (i = 0; i < count; i++) {
108 : : const struct slca_entry *s_entry;
109 : : unsigned int entry_sz;
110 : :
111 : 11 : s_entry = HDIF_get_iarray_item(slca_hdr, SLCA_IDATA_ARRAY,
112 : : i, &entry_sz);
113 : 11 : if (s_entry &&
114 : 11 : VPD_ID(s_entry->fru_id[0],
115 : 11 : s_entry->fru_id[1]) == sai_fru_id) {
116 : 1 : prlog(PR_TRACE, "SLCA: SAI index: 0x%x\n",
117 : : s_entry->my_index);
118 : 1 : prlog(PR_TRACE, "SLCA: SAI location code: %s\n",
119 : : s_entry->loc_code);
120 : 1 : return s_entry;
121 : : }
122 : : }
123 : :
124 : 0 : return NULL;
125 : : }
126 : :
127 : : /*
128 : : * SLCA structure contains System Attention Indicator location
129 : : * code (FRU ID = SA). Add this information to device tree
130 : : * (under '/ibm,opal/led').
131 : : */
132 : 1 : void slca_dt_add_sai_node(void)
133 : : {
134 : : const struct slca_entry *s_entry;
135 : : struct dt_node *led_node, *sai_node;
136 : :
137 : 1 : s_entry = slca_get_sai_entry();
138 : 1 : if (!s_entry)
139 : 0 : return;
140 : :
141 : : /* Create /ibm,opal node, if its not created already */
142 : 1 : if (!opal_node)
143 : 0 : return;
144 : :
145 : : /* Crete LED parent node */
146 : 1 : led_node = dt_find_by_path(opal_node, DT_PROPERTY_LED_NODE);
147 : 1 : if (!led_node)
148 : 0 : return;
149 : :
150 : 1 : if (s_entry->loc_code_len == 0 ||
151 : 1 : s_entry->loc_code_len > LOC_CODE_SIZE)
152 : 0 : return;
153 : :
154 : : /* Create SAI node */
155 : 1 : sai_node = dt_new(led_node, s_entry->loc_code);
156 : 1 : assert(sai_node);
157 : :
158 : 1 : dt_add_property_string(sai_node,
159 : : DT_PROPERTY_LED_TYPES, LED_TYPE_ATTENTION);
160 : : }
|