Message ID | 20250422085717.2605520-5-o.rempel@pengutronix.de |
---|---|
State | New |
Headers | show |
Series | Introduction of PSCR Framework and Related Components | expand |
Hi, On Tue, Apr 22, 2025 at 10:57:14AM +0200, Oleksij Rempel wrote: > Add nvmem_cell_get_size() function to provide access to cell size > metrics. In some cases we may get cell size less as consumer would > expect it. So, nvmem_cell_write() would fail with incorrect buffer size. > > Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de> > --- > changes v6: > - update function comment for nvmem_cell_get_size() > --- This is also needed for the following patch: https://lore.kernel.org/linux-pm/20250321161449.1175473-1-jberring@redhat.com/ Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com> -- Sebastian > drivers/nvmem/core.c | 29 +++++++++++++++++++++++++++++ > include/linux/nvmem-consumer.h | 7 +++++++ > 2 files changed, 36 insertions(+) > > diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c > index fff85bbf0ecd..754a9448c39d 100644 > --- a/drivers/nvmem/core.c > +++ b/drivers/nvmem/core.c > @@ -1828,6 +1828,35 @@ int nvmem_cell_write(struct nvmem_cell *cell, void *buf, size_t len) > > EXPORT_SYMBOL_GPL(nvmem_cell_write); > > +/** > + * nvmem_cell_get_size() - Retrieve the storage size of an NVMEM cell. > + * @cell: Pointer to the NVMEM cell structure. > + * @bytes: Optional pointer to store the cell size in bytes (can be NULL). > + * @bits: Optional pointer to store the cell size in bits (can be NULL). > + * > + * This function allows consumers to retrieve the size of a specific NVMEM > + * cell before performing read/write operations. It is useful for validating > + * buffer sizes to prevent mismatched writes. > + * > + * Return: 0 on success or negative on failure. > + */ > +int nvmem_cell_get_size(struct nvmem_cell *cell, size_t *bytes, size_t *bits) > +{ > + struct nvmem_cell_entry *entry = cell->entry; > + > + if (!entry->nvmem) > + return -EINVAL; > + > + if (bytes) > + *bytes = entry->bytes; > + > + if (bits) > + *bits = entry->nbits; > + > + return 0; > +} > +EXPORT_SYMBOL_GPL(nvmem_cell_get_size); > + > static int nvmem_cell_read_common(struct device *dev, const char *cell_id, > void *val, size_t count) > { > diff --git a/include/linux/nvmem-consumer.h b/include/linux/nvmem-consumer.h > index 34c0e58dfa26..bcb0e17e415d 100644 > --- a/include/linux/nvmem-consumer.h > +++ b/include/linux/nvmem-consumer.h > @@ -56,6 +56,7 @@ void nvmem_cell_put(struct nvmem_cell *cell); > void devm_nvmem_cell_put(struct device *dev, struct nvmem_cell *cell); > void *nvmem_cell_read(struct nvmem_cell *cell, size_t *len); > int nvmem_cell_write(struct nvmem_cell *cell, void *buf, size_t len); > +int nvmem_cell_get_size(struct nvmem_cell *cell, size_t *bytes, size_t *bits); > int nvmem_cell_read_u8(struct device *dev, const char *cell_id, u8 *val); > int nvmem_cell_read_u16(struct device *dev, const char *cell_id, u16 *val); > int nvmem_cell_read_u32(struct device *dev, const char *cell_id, u32 *val); > @@ -128,6 +129,12 @@ static inline int nvmem_cell_write(struct nvmem_cell *cell, > return -EOPNOTSUPP; > } > > +static inline int nvmem_cell_get_size(struct nvmem_cell *cell, size_t *bytes, > + size_t *bits) > +{ > + return -EOPNOTSUPP; > +} > + > static inline int nvmem_cell_read_u8(struct device *dev, > const char *cell_id, u8 *val) > { > -- > 2.39.5 >
diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c index fff85bbf0ecd..754a9448c39d 100644 --- a/drivers/nvmem/core.c +++ b/drivers/nvmem/core.c @@ -1828,6 +1828,35 @@ int nvmem_cell_write(struct nvmem_cell *cell, void *buf, size_t len) EXPORT_SYMBOL_GPL(nvmem_cell_write); +/** + * nvmem_cell_get_size() - Retrieve the storage size of an NVMEM cell. + * @cell: Pointer to the NVMEM cell structure. + * @bytes: Optional pointer to store the cell size in bytes (can be NULL). + * @bits: Optional pointer to store the cell size in bits (can be NULL). + * + * This function allows consumers to retrieve the size of a specific NVMEM + * cell before performing read/write operations. It is useful for validating + * buffer sizes to prevent mismatched writes. + * + * Return: 0 on success or negative on failure. + */ +int nvmem_cell_get_size(struct nvmem_cell *cell, size_t *bytes, size_t *bits) +{ + struct nvmem_cell_entry *entry = cell->entry; + + if (!entry->nvmem) + return -EINVAL; + + if (bytes) + *bytes = entry->bytes; + + if (bits) + *bits = entry->nbits; + + return 0; +} +EXPORT_SYMBOL_GPL(nvmem_cell_get_size); + static int nvmem_cell_read_common(struct device *dev, const char *cell_id, void *val, size_t count) { diff --git a/include/linux/nvmem-consumer.h b/include/linux/nvmem-consumer.h index 34c0e58dfa26..bcb0e17e415d 100644 --- a/include/linux/nvmem-consumer.h +++ b/include/linux/nvmem-consumer.h @@ -56,6 +56,7 @@ void nvmem_cell_put(struct nvmem_cell *cell); void devm_nvmem_cell_put(struct device *dev, struct nvmem_cell *cell); void *nvmem_cell_read(struct nvmem_cell *cell, size_t *len); int nvmem_cell_write(struct nvmem_cell *cell, void *buf, size_t len); +int nvmem_cell_get_size(struct nvmem_cell *cell, size_t *bytes, size_t *bits); int nvmem_cell_read_u8(struct device *dev, const char *cell_id, u8 *val); int nvmem_cell_read_u16(struct device *dev, const char *cell_id, u16 *val); int nvmem_cell_read_u32(struct device *dev, const char *cell_id, u32 *val); @@ -128,6 +129,12 @@ static inline int nvmem_cell_write(struct nvmem_cell *cell, return -EOPNOTSUPP; } +static inline int nvmem_cell_get_size(struct nvmem_cell *cell, size_t *bytes, + size_t *bits) +{ + return -EOPNOTSUPP; +} + static inline int nvmem_cell_read_u8(struct device *dev, const char *cell_id, u8 *val) {
Add nvmem_cell_get_size() function to provide access to cell size metrics. In some cases we may get cell size less as consumer would expect it. So, nvmem_cell_write() would fail with incorrect buffer size. Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de> --- changes v6: - update function comment for nvmem_cell_get_size() --- drivers/nvmem/core.c | 29 +++++++++++++++++++++++++++++ include/linux/nvmem-consumer.h | 7 +++++++ 2 files changed, 36 insertions(+)