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