Re: [PATCH] nvmem: core: Allow sub-register width nvmem_regmap_write()

Ahmad Fatoum <[email protected]>
Newsgroups org.infradead.lists.barebox
Message-ID <[email protected]>
On 5/25/26 13:45, Jonas Rebmann wrote:
> From: Ahmad Fatoum <[email protected]>
> 
> The previous implementation of nvmem_regmap_write() required the
> supplied value to be a multiple of the register size defined by the
> driver ("expect users to observe alignment").
> 
> This is however not respected by nvmem cell functions
> nvmem_cell_prepare_write_buffer()/__nvmem_cell_entry_write() which
> prepare the value buffer based on the "bits" supplied in the devicetree,
> resulting in EINVAL errors if an nvmem cell with "bits" spanning less
> bytes than val_bytes = DIV_ROUND_UP(config->val_bits, 8) of the nvmem
> driver.
> 
> To resolve this, accept buffers shorter than val_bytes, and place them
> correctly with regard to endianness.
> 
> Not-Signed-off-by: Ahmad Fatoum <[email protected]>
> Signed-off-by: Jonas Rebmann <[email protected]>
> ---
> Ahmad and me pair-programmed this on friday. Ahmad, can we have your
> SoB?

Signed-off-by: Ahmad Fatoum <[email protected]>

> ---
>  drivers/nvmem/regmap.c | 29 ++++++++++++++++++++++-------
>  1 file changed, 22 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/nvmem/regmap.c b/drivers/nvmem/regmap.c
> index 98e57909eb..22e667af17 100644
> --- a/drivers/nvmem/regmap.c
> +++ b/drivers/nvmem/regmap.c
> @@ -12,16 +12,31 @@
>  static int nvmem_regmap_write(void *ctx, unsigned offset, const void *val, size_t bytes)
>  {
>  	struct regmap *map = ctx;
> +	unsigned int tmp;
>  
> -	/*
> -	 * eFuse writes going through this function may be irreversible,
> -	 * so expect users to observe alignment.
> -	 */
> -	if (bytes % regmap_get_val_bytes(map))
> +	if (bytes > regmap_get_val_bytes(map)) {
> +		if (bytes % regmap_get_val_bytes(map))
> +			return -EINVAL;
> +
> +		return regmap_bulk_write(map, offset, val,
> +					 bytes / regmap_get_val_bytes(map));
> +	}
> +
> +	switch (bytes) {
> +	case 1:
> +		tmp = *(u8 *)val;
> +		break;
> +	case 2:
> +		tmp = *(u16 *)val;
> +		break;
> +	case 4:
> +		tmp = *(u32 *)val;
> +		break;
> +	default:
>  		return -EINVAL;
> +	}
>  
> -	return regmap_bulk_write(map, offset, val,
> -				 bytes / regmap_get_val_bytes(map));
> +	return regmap_write(map, offset, tmp);
>  }
>  
>  static int nvmem_regmap_read(void *ctx, unsigned offset, void *buf, size_t bytes)
> 
> ---
> base-commit: f5956c772dc00837bad36fc66df8a53aae86558d
> change-id: 20260525-short_nvmem_write-86a2114f6774
> 
> Best regards,
> --  
> Jonas Rebmann <[email protected]>
> 
> 


-- 
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 |
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.