On 08.09.21 12:02, Joakim Zhang wrote: > From: Srinivas Kandagatla <srinivas.kandagatla@xxxxxxxxxx> > > Some NVMEM providers have certain nvmem cells encoded, which requires > post processing before actually using it. > > For example mac-address is stored in either in ascii or delimited or reverse-order. > > Having a post-process callback hook to provider drivers would enable them to > do this vendor specific post processing before nvmem consumers see it. > > Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@xxxxxxxxxx> > Signed-off-by: Joakim Zhang <qiangqing.zhang@xxxxxxx> > --- > drivers/nvmem/core.c | 9 +++++++++ > include/linux/nvmem-provider.h | 5 +++++ > 2 files changed, 14 insertions(+) > > diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c > index 23c08dbaf45e..4f81a3adf081 100644 > --- a/drivers/nvmem/core.c > +++ b/drivers/nvmem/core.c > @@ -38,6 +38,7 @@ struct nvmem_device { > unsigned int nkeepout; > nvmem_reg_read_t reg_read; > nvmem_reg_write_t reg_write; > + nvmem_cell_post_process_t cell_post_process; > struct gpio_desc *wp_gpio; > void *priv; > }; > @@ -797,6 +798,7 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config) > nvmem->type = config->type; > nvmem->reg_read = config->reg_read; > nvmem->reg_write = config->reg_write; > + nvmem->cell_post_process = config->cell_post_process; > nvmem->keepout = config->keepout; > nvmem->nkeepout = config->nkeepout; > if (config->of_node) > @@ -1404,6 +1406,13 @@ static int __nvmem_cell_read(struct nvmem_device *nvmem, > if (cell->bit_offset || cell->nbits) > nvmem_shift_read_buffer_in_place(cell, buf); > > + if (nvmem->cell_post_process) { > + rc = nvmem->cell_post_process(nvmem->priv, cell->type, > + cell->offset, buf, cell->bytes); > + if (rc) > + return rc; > + } > + > if (len) > *len = cell->bytes; > > diff --git a/include/linux/nvmem-provider.h b/include/linux/nvmem-provider.h > index 104505e9028f..d980c79f9605 100644 > --- a/include/linux/nvmem-provider.h > +++ b/include/linux/nvmem-provider.h > @@ -19,6 +19,9 @@ typedef int (*nvmem_reg_read_t)(void *priv, unsigned int offset, > void *val, size_t bytes); > typedef int (*nvmem_reg_write_t)(void *priv, unsigned int offset, > void *val, size_t bytes); > +/* used for vendor specific post processing of cell data */ > +typedef int (*nvmem_cell_post_process_t)(void *priv, int type, unsigned int offset, > + void *buf, size_t bytes); > > enum nvmem_type { > NVMEM_TYPE_UNKNOWN = 0, > @@ -62,6 +65,7 @@ struct nvmem_keepout { > * @no_of_node: Device should not use the parent's of_node even if it's !NULL. > * @reg_read: Callback to read data. > * @reg_write: Callback to write data. > + * @cell_read_callback: Callback for vendor specific post processing of cell data The member below is called cell_post_process > * @size: Device size. > * @word_size: Minimum read/write access granularity. > * @stride: Minimum read/write access stride. > @@ -92,6 +96,7 @@ struct nvmem_config { > bool no_of_node; > nvmem_reg_read_t reg_read; > nvmem_reg_write_t reg_write; > + nvmem_cell_post_process_t cell_post_process; > int size; > int word_size; > int stride; > -- Pengutronix e.K. | | Steuerwalder Str. 21 | http://www.pengutronix.de/ | 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |