1515c1ba9SClément Léger // SPDX-License-Identifier: BSD-2-Clause
2515c1ba9SClément Léger /*
3515c1ba9SClément Léger * Copyright (c) 2023, Microchip
4515c1ba9SClément Léger */
5515c1ba9SClément Léger
6515c1ba9SClément Léger #include <drivers/nvmem.h>
7515c1ba9SClément Léger #include <kernel/dt.h>
8515c1ba9SClément Léger #include <libfdt.h>
9515c1ba9SClément Léger
nvmem_cell_parse_dt(const void * fdt,int nodeoffset,struct nvmem_cell * cell)10515c1ba9SClément Léger TEE_Result nvmem_cell_parse_dt(const void *fdt, int nodeoffset,
11515c1ba9SClément Léger struct nvmem_cell *cell)
12515c1ba9SClément Léger {
13*6a0116edSEtienne Carriere if (fdt_reg_info(fdt, nodeoffset, &cell->offset, &cell->len))
14515c1ba9SClément Léger return TEE_ERROR_GENERIC;
15515c1ba9SClément Léger
16515c1ba9SClément Léger return TEE_SUCCESS;
17515c1ba9SClément Léger }
18515c1ba9SClément Léger
nvmem_get_cell_by_name(const void * fdt,int nodeoffset,const char * name,struct nvmem_cell ** cell)19515c1ba9SClément Léger TEE_Result nvmem_get_cell_by_name(const void *fdt, int nodeoffset,
20515c1ba9SClément Léger const char *name, struct nvmem_cell **cell)
21515c1ba9SClément Léger {
22515c1ba9SClément Léger int index = 0;
23515c1ba9SClément Léger
24515c1ba9SClément Léger index = fdt_stringlist_search(fdt, nodeoffset, "nvmem-cell-names",
25515c1ba9SClément Léger name);
26515c1ba9SClément Léger if (index < 0)
27515c1ba9SClément Léger return TEE_ERROR_ITEM_NOT_FOUND;
28515c1ba9SClément Léger
29515c1ba9SClément Léger return nvmem_get_cell_by_index(fdt, nodeoffset, index, cell);
30515c1ba9SClément Léger }
31515c1ba9SClément Léger
nvmem_get_cell_by_index(const void * fdt,int nodeoffset,unsigned int index,struct nvmem_cell ** out_cell)32515c1ba9SClément Léger TEE_Result nvmem_get_cell_by_index(const void *fdt,
33515c1ba9SClément Léger int nodeoffset,
34515c1ba9SClément Léger unsigned int index,
35515c1ba9SClément Léger struct nvmem_cell **out_cell)
36515c1ba9SClément Léger {
37515c1ba9SClément Léger TEE_Result res = TEE_ERROR_GENERIC;
38515c1ba9SClément Léger void *cell = NULL;
39515c1ba9SClément Léger
40515c1ba9SClément Léger res = dt_driver_device_from_node_idx_prop("nvmem-cells", fdt,
41515c1ba9SClément Léger nodeoffset, index,
42515c1ba9SClément Léger DT_DRIVER_NVMEM, &cell);
43515c1ba9SClément Léger if (!res)
44515c1ba9SClément Léger *out_cell = cell;
45515c1ba9SClément Léger
46515c1ba9SClément Léger return res;
47515c1ba9SClément Léger }
48515c1ba9SClément Léger
nvmem_cell_malloc_and_read(struct nvmem_cell * cell,uint8_t ** out_data)49515c1ba9SClément Léger TEE_Result nvmem_cell_malloc_and_read(struct nvmem_cell *cell,
50515c1ba9SClément Léger uint8_t **out_data)
51515c1ba9SClément Léger {
52515c1ba9SClément Léger TEE_Result res = TEE_ERROR_GENERIC;
53515c1ba9SClément Léger
54515c1ba9SClément Léger if (!cell->ops->read_cell)
55515c1ba9SClément Léger return TEE_ERROR_NOT_SUPPORTED;
56515c1ba9SClément Léger
57515c1ba9SClément Léger *out_data = malloc(cell->len);
58515c1ba9SClément Léger if (!out_data)
59515c1ba9SClément Léger return TEE_ERROR_OUT_OF_MEMORY;
60515c1ba9SClément Léger
61515c1ba9SClément Léger res = cell->ops->read_cell(cell, *out_data);
62515c1ba9SClément Léger if (res)
63515c1ba9SClément Léger free(*out_data);
64515c1ba9SClément Léger
65515c1ba9SClément Léger return res;
66515c1ba9SClément Léger }
67