Line data Source code
1 1 : /*
2 : * Copyright (c) 2020 Intel Corporation
3 : *
4 : * SPDX-License-Identifier: Apache-2.0
5 : */
6 :
7 : /**
8 : * @file
9 : * @brief EDAC API header file
10 : */
11 :
12 : #ifndef ZEPHYR_INCLUDE_DRIVERS_EDAC_H_
13 : #define ZEPHYR_INCLUDE_DRIVERS_EDAC_H_
14 :
15 : #include <errno.h>
16 :
17 : #include <sys/types.h>
18 :
19 : /**
20 : * @defgroup edac EDAC API
21 : * @since 2.5
22 : * @version 0.8.0
23 : * @ingroup io_interfaces
24 : * @{
25 : */
26 :
27 : /**
28 : * @brief EDAC error type
29 : */
30 1 : enum edac_error_type {
31 : /** Correctable error type */
32 : EDAC_ERROR_TYPE_DRAM_COR = BIT(0),
33 : /** Uncorrectable error type */
34 : EDAC_ERROR_TYPE_DRAM_UC = BIT(1)
35 : };
36 :
37 : /**
38 : * @cond INTERNAL_HIDDEN
39 : *
40 : * For internal use only, skip these in public documentation.
41 : */
42 :
43 : typedef void (*edac_notify_callback_f)(const struct device *dev, void *data);
44 :
45 : /**
46 : * @brief EDAC driver API
47 : *
48 : * This is the mandatory API any EDAC driver needs to expose.
49 : */
50 : __subsystem struct edac_driver_api {
51 : /* Error Injection API is disabled by default */
52 : int (*inject_set_param1)(const struct device *dev, uint64_t value);
53 : int (*inject_get_param1)(const struct device *dev, uint64_t *value);
54 : int (*inject_set_param2)(const struct device *dev, uint64_t value);
55 : int (*inject_get_param2)(const struct device *dev, uint64_t *value);
56 : int (*inject_set_error_type)(const struct device *dev, uint32_t value);
57 : int (*inject_get_error_type)(const struct device *dev, uint32_t *value);
58 : int (*inject_error_trigger)(const struct device *dev);
59 :
60 : /* Error Logging API */
61 : int (*ecc_error_log_get)(const struct device *dev, uint64_t *value);
62 : int (*ecc_error_log_clear)(const struct device *dev);
63 : int (*parity_error_log_get)(const struct device *dev, uint64_t *value);
64 : int (*parity_error_log_clear)(const struct device *dev);
65 :
66 : /* Error stats API */
67 : int (*errors_cor_get)(const struct device *dev);
68 : int (*errors_uc_get)(const struct device *dev);
69 :
70 : /* Notification callback API */
71 : int (*notify_cb_set)(const struct device *dev,
72 : edac_notify_callback_f cb);
73 : };
74 :
75 : /**
76 : * INTERNAL_HIDDEN @endcond
77 : */
78 :
79 : /**
80 : * @name Optional interfaces
81 : * @{
82 : *
83 : * EDAC Optional Interfaces
84 : */
85 :
86 : /**
87 : * @brief Set injection parameter param1
88 : *
89 : * Set first error injection parameter value.
90 : *
91 : * @param dev Pointer to the device structure
92 : * @param value First injection parameter
93 : *
94 : * @retval -ENOSYS if the optional interface is not implemented
95 : * @retval 0 on success, other error code otherwise
96 : */
97 1 : static inline int edac_inject_set_param1(const struct device *dev,
98 : uint64_t value)
99 : {
100 : const struct edac_driver_api *api =
101 : (const struct edac_driver_api *)dev->api;
102 :
103 : if (api->inject_set_param1 == NULL) {
104 : return -ENOSYS;
105 : }
106 :
107 : return api->inject_set_param1(dev, value);
108 : }
109 :
110 : /**
111 : * @brief Get injection parameter param1
112 : *
113 : * Get first error injection parameter value.
114 : *
115 : * @param dev Pointer to the device structure
116 : * @param value Pointer to the first injection parameter
117 : *
118 : * @retval -ENOSYS if the optional interface is not implemented
119 : * @retval 0 on success, error code otherwise
120 : */
121 1 : static inline int edac_inject_get_param1(const struct device *dev,
122 : uint64_t *value)
123 : {
124 : const struct edac_driver_api *api =
125 : (const struct edac_driver_api *)dev->api;
126 :
127 : if (api->inject_get_param1 == NULL) {
128 : return -ENOSYS;
129 : }
130 :
131 : return api->inject_get_param1(dev, value);
132 :
133 : }
134 :
135 : /**
136 : * @brief Set injection parameter param2
137 : *
138 : * Set second error injection parameter value.
139 : *
140 : * @param dev Pointer to the device structure
141 : * @param value Second injection parameter
142 : *
143 : * @retval -ENOSYS if the optional interface is not implemented
144 : * @retval 0 on success, error code otherwise
145 : */
146 1 : static inline int edac_inject_set_param2(const struct device *dev,
147 : uint64_t value)
148 : {
149 : const struct edac_driver_api *api =
150 : (const struct edac_driver_api *)dev->api;
151 :
152 : if (api->inject_set_param2 == NULL) {
153 : return -ENOSYS;
154 : }
155 :
156 : return api->inject_set_param2(dev, value);
157 : }
158 :
159 : /**
160 : * @brief Get injection parameter param2
161 : *
162 : * @param dev Pointer to the device structure
163 : * @param value Pointer to the second injection parameter
164 : *
165 : * @retval -ENOSYS if the optional interface is not implemented
166 : * @retval 0 on success, error code otherwise
167 : */
168 1 : static inline int edac_inject_get_param2(const struct device *dev,
169 : uint64_t *value)
170 : {
171 : const struct edac_driver_api *api =
172 : (const struct edac_driver_api *)dev->api;
173 :
174 : if (api->inject_get_param2 == NULL) {
175 : return -ENOSYS;
176 : }
177 :
178 : return api->inject_get_param2(dev, value);
179 : }
180 :
181 : /**
182 : * @brief Set error type value
183 : *
184 : * Set the value of error type to be injected
185 : *
186 : * @param dev Pointer to the device structure
187 : * @param error_type Error type value
188 : *
189 : * @retval -ENOSYS if the optional interface is not implemented
190 : * @retval 0 on success, error code otherwise
191 : */
192 1 : static inline int edac_inject_set_error_type(const struct device *dev,
193 : uint32_t error_type)
194 : {
195 : const struct edac_driver_api *api =
196 : (const struct edac_driver_api *)dev->api;
197 :
198 : if (api->inject_set_error_type == NULL) {
199 : return -ENOSYS;
200 : }
201 :
202 : return api->inject_set_error_type(dev, error_type);
203 : }
204 :
205 : /**
206 : * @brief Get error type value
207 : *
208 : * Get the value of error type to be injected
209 : *
210 : * @param dev Pointer to the device structure
211 : * @param error_type Pointer to error type value
212 : *
213 : * @retval -ENOSYS if the optional interface is not implemented
214 : * @retval 0 on success, error code otherwise
215 : */
216 1 : static inline int edac_inject_get_error_type(const struct device *dev,
217 : uint32_t *error_type)
218 : {
219 : const struct edac_driver_api *api =
220 : (const struct edac_driver_api *)dev->api;
221 :
222 : if (api->inject_get_error_type == NULL) {
223 : return -ENOSYS;
224 : }
225 :
226 : return api->inject_get_error_type(dev, error_type);
227 : }
228 :
229 : /**
230 : * @brief Set injection control
231 : *
232 : * Trigger error injection.
233 : *
234 : * @param dev Pointer to the device structure
235 : *
236 : * @retval -ENOSYS if the optional interface is not implemented
237 : * @retval 0 on success, error code otherwise
238 : */
239 1 : static inline int edac_inject_error_trigger(const struct device *dev)
240 : {
241 : const struct edac_driver_api *api =
242 : (const struct edac_driver_api *)dev->api;
243 :
244 : if (api->inject_error_trigger == NULL) {
245 : return -ENOSYS;
246 : }
247 :
248 : return api->inject_error_trigger(dev);
249 : }
250 :
251 : /** @} */ /* End of EDAC Optional Interfaces */
252 :
253 : /**
254 : * @name Mandatory interfaces
255 : * @{
256 : *
257 : * EDAC Mandatory Interfaces
258 : */
259 :
260 : /**
261 : * @brief Get ECC Error Log
262 : *
263 : * Read value of ECC Error Log.
264 : *
265 : * @param dev Pointer to the device structure
266 : * @param value Pointer to the ECC Error Log value
267 : *
268 : * @retval 0 on success, error code otherwise
269 : * @retval -ENOSYS if the mandatory interface is not implemented
270 : */
271 1 : static inline int edac_ecc_error_log_get(const struct device *dev,
272 : uint64_t *value)
273 : {
274 : const struct edac_driver_api *api =
275 : (const struct edac_driver_api *)dev->api;
276 :
277 : if (api->ecc_error_log_get == NULL) {
278 : return -ENOSYS;
279 : }
280 :
281 : return api->ecc_error_log_get(dev, value);
282 : }
283 :
284 : /**
285 : * @brief Clear ECC Error Log
286 : *
287 : * Clear value of ECC Error Log.
288 : *
289 : * @param dev Pointer to the device structure
290 : *
291 : * @retval 0 on success, error code otherwise
292 : * @retval -ENOSYS if the mandatory interface is not implemented
293 : */
294 1 : static inline int edac_ecc_error_log_clear(const struct device *dev)
295 : {
296 : const struct edac_driver_api *api =
297 : (const struct edac_driver_api *)dev->api;
298 :
299 : if (api->ecc_error_log_clear == NULL) {
300 : return -ENOSYS;
301 : }
302 :
303 : return api->ecc_error_log_clear(dev);
304 : }
305 :
306 : /**
307 : * @brief Get Parity Error Log
308 : *
309 : * Read value of Parity Error Log.
310 : *
311 : * @param dev Pointer to the device structure
312 : * @param value Pointer to the parity Error Log value
313 : *
314 : * @retval 0 on success, error code otherwise
315 : * @retval -ENOSYS if the mandatory interface is not implemented
316 : */
317 1 : static inline int edac_parity_error_log_get(const struct device *dev,
318 : uint64_t *value)
319 : {
320 : const struct edac_driver_api *api =
321 : (const struct edac_driver_api *)dev->api;
322 :
323 : if (api->parity_error_log_get == NULL) {
324 : return -ENOSYS;
325 : }
326 :
327 : return api->parity_error_log_get(dev, value);
328 : }
329 :
330 : /**
331 : * @brief Clear Parity Error Log
332 : *
333 : * Clear value of Parity Error Log.
334 : *
335 : * @param dev Pointer to the device structure
336 : *
337 : * @retval 0 on success, error code otherwise
338 : * @retval -ENOSYS if the mandatory interface is not implemented
339 : */
340 1 : static inline int edac_parity_error_log_clear(const struct device *dev)
341 : {
342 : const struct edac_driver_api *api =
343 : (const struct edac_driver_api *)dev->api;
344 :
345 : if (api->parity_error_log_clear == NULL) {
346 : return -ENOSYS;
347 : }
348 :
349 : return api->parity_error_log_clear(dev);
350 : }
351 :
352 : /**
353 : * @brief Get number of correctable errors
354 : *
355 : * @param dev Pointer to the device structure
356 : *
357 : * @retval num Number of correctable errors
358 : * @retval -ENOSYS if the mandatory interface is not implemented
359 : */
360 1 : static inline int edac_errors_cor_get(const struct device *dev)
361 : {
362 : const struct edac_driver_api *api =
363 : (const struct edac_driver_api *)dev->api;
364 :
365 : if (api->errors_cor_get == NULL) {
366 : return -ENOSYS;
367 : }
368 :
369 : return api->errors_cor_get(dev);
370 : }
371 :
372 : /**
373 : * @brief Get number of uncorrectable errors
374 : *
375 : * @param dev Pointer to the device structure
376 : *
377 : * @retval num Number of uncorrectable errors
378 : * @retval -ENOSYS if the mandatory interface is not implemented
379 : */
380 1 : static inline int edac_errors_uc_get(const struct device *dev)
381 : {
382 : const struct edac_driver_api *api =
383 : (const struct edac_driver_api *)dev->api;
384 :
385 : if (api->errors_uc_get == NULL) {
386 : return -ENOSYS;
387 : }
388 :
389 : return api->errors_uc_get(dev);
390 : }
391 :
392 : /**
393 : * Register callback function for memory error exception
394 : *
395 : * This callback runs in interrupt context
396 : *
397 : * @param dev EDAC driver device to install callback
398 : * @param cb Callback function pointer
399 : *
400 : * @retval 0 on success, error code otherwise
401 : * @retval -ENOSYS if the mandatory interface is not implemented
402 : */
403 1 : static inline int edac_notify_callback_set(const struct device *dev,
404 : edac_notify_callback_f cb)
405 : {
406 : const struct edac_driver_api *api = (const struct edac_driver_api *)dev->api;
407 :
408 : if (api->notify_cb_set == NULL) {
409 : return -ENOSYS;
410 : }
411 :
412 : return api->notify_cb_set(dev, cb);
413 : }
414 :
415 :
416 : /** @} */ /* End of EDAC Mandatory Interfaces */
417 :
418 : /** @} */ /* End of EDAC API */
419 :
420 : #endif /* ZEPHYR_INCLUDE_DRIVERS_EDAC_H_ */
|