We already have nvmem_cell_get_and_read(), so add its Linux sibling nvmem_cell_read_variable_le_u32 as well, which additionally takes care of conversion to little-endian. Signed-off-by: Ahmad Fatoum <a.fatoum@xxxxxxxxxxxxxx> --- drivers/nvmem/core.c | 33 +++++++++++++++++++++++++++++++++ include/linux/nvmem-consumer.h | 9 +++++++++ 2 files changed, 42 insertions(+) diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c index fed387c43a26..c5fe5f6b767a 100644 --- a/drivers/nvmem/core.c +++ b/drivers/nvmem/core.c @@ -803,3 +803,36 @@ void *nvmem_cell_get_and_read(struct device_node *np, const char *cell_name, return value; } EXPORT_SYMBOL_GPL(nvmem_cell_get_and_read); + +/** + * nvmem_cell_read_variable_le_u32() - Read up to 32-bits of data as a little endian number. + * + * @dev: Device that requests the nvmem cell. + * @cell_id: Name of nvmem cell to read. + * @val: pointer to output value. + * + * Return: 0 on success or negative errno. + */ +int nvmem_cell_read_variable_le_u32(struct device_d *dev, const char *cell_id, + u32 *val) +{ + size_t len; + const u8 *buf; + int i; + + len = sizeof(*val); + + buf = nvmem_cell_get_and_read(dev->device_node, cell_id, len); + if (IS_ERR(buf)) + return PTR_ERR(buf); + + /* Copy w/ implicit endian conversion */ + *val = 0; + for (i = 0; i < len; i++) + *val |= buf[i] << (8 * i); + + kfree(buf); + + return 0; +} +EXPORT_SYMBOL_GPL(nvmem_cell_read_variable_le_u32); diff --git a/include/linux/nvmem-consumer.h b/include/linux/nvmem-consumer.h index b979f23372a6..b461f840957e 100644 --- a/include/linux/nvmem-consumer.h +++ b/include/linux/nvmem-consumer.h @@ -34,6 +34,8 @@ void nvmem_cell_put(struct nvmem_cell *cell); void *nvmem_cell_read(struct nvmem_cell *cell, size_t *len); void *nvmem_cell_get_and_read(struct device_node *np, const char *cell_name, size_t bytes); +int nvmem_cell_read_variable_le_u32(struct device_d *dev, const char *cell_id, + u32 *val); int nvmem_cell_write(struct nvmem_cell *cell, void *buf, size_t len); @@ -75,6 +77,13 @@ static inline void *nvmem_cell_get_and_read(struct device_node *np, return ERR_PTR(-EOPNOTSUPP); } +static inline int nvmem_cell_read_variable_le_u32(struct device_d *dev, + const char *cell_id, + u32 *val) +{ + return ERR_PTR(-EOPNOTSUPP); +} + static inline int nvmem_cell_write(struct nvmem_cell *cell, void *buf, size_t len) { -- 2.30.2