xref: /optee_os/core/drivers/nvmem/nvmem.c (revision af3fb62410645ac9636d27c3d1db72c0c9fca913)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2023, Microchip
4  */
5 
6 #include <drivers/nvmem.h>
7 #include <kernel/dt.h>
8 #include <libfdt.h>
9 
10 TEE_Result nvmem_cell_parse_dt(const void *fdt, int nodeoffset,
11 			       struct nvmem_cell *cell)
12 {
13 	size_t buf_len = 0;
14 	paddr_t offset = 0;
15 
16 	buf_len = fdt_reg_size(fdt, nodeoffset);
17 	if (buf_len == DT_INFO_INVALID_REG_SIZE)
18 		return TEE_ERROR_GENERIC;
19 
20 	offset = fdt_reg_base_address(fdt, nodeoffset);
21 	if (offset == DT_INFO_INVALID_REG)
22 		return TEE_ERROR_GENERIC;
23 
24 	cell->len = buf_len;
25 	cell->offset = offset;
26 
27 	return TEE_SUCCESS;
28 }
29 
30 TEE_Result nvmem_get_cell_by_name(const void *fdt, int nodeoffset,
31 				  const char *name, struct nvmem_cell **cell)
32 {
33 	int index = 0;
34 
35 	index = fdt_stringlist_search(fdt, nodeoffset, "nvmem-cell-names",
36 				      name);
37 	if (index < 0)
38 		return TEE_ERROR_ITEM_NOT_FOUND;
39 
40 	return nvmem_get_cell_by_index(fdt, nodeoffset, index, cell);
41 }
42 
43 TEE_Result nvmem_get_cell_by_index(const void *fdt,
44 				   int nodeoffset,
45 				   unsigned int index,
46 				   struct nvmem_cell **out_cell)
47 {
48 	TEE_Result res = TEE_ERROR_GENERIC;
49 	void *cell = NULL;
50 
51 	res = dt_driver_device_from_node_idx_prop("nvmem-cells", fdt,
52 						  nodeoffset, index,
53 						  DT_DRIVER_NVMEM, &cell);
54 	if (!res)
55 		*out_cell = cell;
56 
57 	return res;
58 }
59 
60 TEE_Result nvmem_cell_malloc_and_read(struct nvmem_cell *cell,
61 				      uint8_t **out_data)
62 {
63 	TEE_Result res = TEE_ERROR_GENERIC;
64 
65 	if (!cell->ops->read_cell)
66 		return TEE_ERROR_NOT_SUPPORTED;
67 
68 	*out_data = malloc(cell->len);
69 	if (!out_data)
70 		return TEE_ERROR_OUT_OF_MEMORY;
71 
72 	res = cell->ops->read_cell(cell, *out_data);
73 	if (res)
74 		free(*out_data);
75 
76 	return res;
77 }
78