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