lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <cfdff4f068c98feba252b28fb61de7629637dc45.camel@gmail.com>
Date: Thu, 14 Aug 2025 14:24:06 +0200
From: Alexander Sverdlin <alexander.sverdlin@...il.com>
To: Markus Heidelberg <m.heidelberg@....de>, Arnd Bergmann <arnd@...db.de>, 
 Greg Kroah-Hartman <gregkh@...uxfoundation.org>, devicetree@...r.kernel.org
Cc: Rob Herring <robh@...nel.org>, Krzysztof Kozlowski <krzk+dt@...nel.org>,
  Conor Dooley <conor+dt@...nel.org>, Christian Eggers <ceggers@...i.de>,
 Jiri Prchal <jiri.prchal@...ignal.cz>, 	linux-kernel@...r.kernel.org
Subject: Re: [PATCH 2/3] eeprom: at25: support Cypress FRAMs without device
 ID

On Thu, 2025-08-14 at 13:15 +0200, Markus Heidelberg wrote:
> Not all FRAM chips have a device ID and implement the corresponding read
> command. For such chips this led to the following error on module
> loading:
> 
>     at25 spi2.0: Error: no Cypress FRAM (id 00)
> 
> The device ID contains the memory size, so devices without this ID are
> supported now by setting the size manually in Devicetree using the
> "size" property.
> 
> Tested with FM25L16B and "size = <2048>;":
> 
>     at25 spi2.0: 2 KByte fm25 fram, pagesize 4096
> 
> According to Infineon/Cypress datasheets, these FRAMs have a device ID:
> 
>     FM25V01A
>     FM25V02A
>     FM25V05
>     FM25V10
>     FM25V20A
>     FM25VN10
> 
> but these do not:
> 
>     FM25040B
>     FM25640B
>     FM25C160B
>     FM25CL64B
>     FM25L04B
>     FM25L16B
>     FM25W256
> 
> So all "FM25V*" FRAMs and only these have a device ID. The letter after
> "FM25" (V/C/L/W) only describes the voltage range, though.
> 
> Link: https://lore.kernel.org/all/20250401133148.38330-1-m.heidelberg@cab.de/
> Signed-off-by: Markus Heidelberg <m.heidelberg@....de>

Reviewed-by: Alexander Sverdlin <alexander.sverdlin@...il.com>

> ---
>  drivers/misc/eeprom/at25.c | 67 ++++++++++++++++++++------------------
>  1 file changed, 36 insertions(+), 31 deletions(-)
> 
> diff --git a/drivers/misc/eeprom/at25.c b/drivers/misc/eeprom/at25.c
> index 2d0492867054..c90150f72836 100644
> --- a/drivers/misc/eeprom/at25.c
> +++ b/drivers/misc/eeprom/at25.c
> @@ -379,37 +379,49 @@ static int at25_fram_to_chip(struct device *dev, struct spi_eeprom *chip)
>  	struct at25_data *at25 = container_of(chip, struct at25_data, chip);
>  	u8 sernum[FM25_SN_LEN];
>  	u8 id[FM25_ID_LEN];
> +	u32 val;
>  	int i;
>  
>  	strscpy(chip->name, "fm25", sizeof(chip->name));
>  
> -	/* Get ID of chip */
> -	fm25_aux_read(at25, id, FM25_RDID, FM25_ID_LEN);
> -	/* There are inside-out FRAM variations, detect them and reverse the ID bytes */
> -	if (id[6] == 0x7f && id[2] == 0xc2)
> -		for (i = 0; i < ARRAY_SIZE(id) / 2; i++) {
> -			u8 tmp = id[i];
> -			int j = ARRAY_SIZE(id) - i - 1;
> +	if (!device_property_read_u32(dev, "size", &val)) {
> +		chip->byte_len = val;
> +	} else {
> +		/* Get ID of chip */
> +		fm25_aux_read(at25, id, FM25_RDID, FM25_ID_LEN);
> +		/* There are inside-out FRAM variations, detect them and reverse the ID bytes */
> +		if (id[6] == 0x7f && id[2] == 0xc2)
> +			for (i = 0; i < ARRAY_SIZE(id) / 2; i++) {
> +				u8 tmp = id[i];
> +				int j = ARRAY_SIZE(id) - i - 1;
> +
> +				id[i] = id[j];
> +				id[j] = tmp;
> +			}
> +		if (id[6] != 0xc2) {
> +			dev_err(dev, "Error: no Cypress FRAM (id %02x)\n", id[6]);
> +			return -ENODEV;
> +		}
>  
> -			id[i] = id[j];
> -			id[j] = tmp;
> +		switch (id[7]) {
> +		case 0x21 ... 0x26:
> +			chip->byte_len = BIT(id[7] - 0x21 + 4) * 1024;
> +			break;
> +		case 0x2a ... 0x30:
> +			/* CY15B116QN ... CY15B116QN */
> +			chip->byte_len = BIT(((id[7] >> 1) & 0xf) + 13);
> +			break;
> +		default:
> +			dev_err(dev, "Error: unsupported size (id %02x)\n", id[7]);
> +			return -ENODEV;
>  		}
> -	if (id[6] != 0xc2) {
> -		dev_err(dev, "Error: no Cypress FRAM (id %02x)\n", id[6]);
> -		return -ENODEV;
> -	}
>  
> -	switch (id[7]) {
> -	case 0x21 ... 0x26:
> -		chip->byte_len = BIT(id[7] - 0x21 + 4) * 1024;
> -		break;
> -	case 0x2a ... 0x30:
> -		/* CY15B116QN ... CY15B116QN */
> -		chip->byte_len = BIT(((id[7] >> 1) & 0xf) + 13);
> -		break;
> -	default:
> -		dev_err(dev, "Error: unsupported size (id %02x)\n", id[7]);
> -		return -ENODEV;
> +		if (id[8]) {
> +			fm25_aux_read(at25, sernum, FM25_RDSN, FM25_SN_LEN);
> +			/* Swap byte order */
> +			for (i = 0; i < FM25_SN_LEN; i++)
> +				at25->sernum[i] = sernum[FM25_SN_LEN - 1 - i];
> +		}
>  	}
>  
>  	if (chip->byte_len > 64 * 1024)
> @@ -417,13 +429,6 @@ static int at25_fram_to_chip(struct device *dev, struct spi_eeprom *chip)
>  	else
>  		chip->flags |= EE_ADDR2;
>  
> -	if (id[8]) {
> -		fm25_aux_read(at25, sernum, FM25_RDSN, FM25_SN_LEN);
> -		/* Swap byte order */
> -		for (i = 0; i < FM25_SN_LEN; i++)
> -			at25->sernum[i] = sernum[FM25_SN_LEN - 1 - i];
> -	}
> -
>  	chip->page_size = PAGE_SIZE;
>  	return 0;
>  }
> --
> 2.43.0

-- 
Alexander Sverdlin.

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ