Re: [PATCH 1/1] mtd: spi-nor: add a presence check for non-JEDEC spi nor

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi, Flavio, Marek, Vignesh,

On 06/24/2019 10:07 AM, Flavio Suligoi wrote:
> External E-Mail
> 
> 
> Hi Tudor,
> 
>> -----Original Message-----
>> From: Tudor.Ambarus@xxxxxxxxxxxxx <Tudor.Ambarus@xxxxxxxxxxxxx>
>> Sent: domenica 23 giugno 2019 06:00
>> To: Flavio Suligoi <f.suligoi@xxxxxxx>; marek.vasut@xxxxxxxxx;
>> dwmw2@xxxxxxxxxxxxx; computersforpeace@xxxxxxxxx; bbrezillon@xxxxxxxxxx;
>> richard@xxxxxx
>> Cc: linux-mtd@xxxxxxxxxxxxxxxxxxx; linux-kernel@xxxxxxxxxxxxxx
>> Subject: Re: [PATCH 1/1] mtd: spi-nor: add a presence check for non-JEDEC
>> spi nor
>>
>> Hi, Flavio,
>>
>> On 03/21/2019 02:55 PM, Flavio Suligoi wrote:
>>> External E-Mail
>>>
>>>
>>> This patch fixes the following kernel error message:
>>>
>>> "flash operation timed out"
>>>
>>> that occurs when a non-JEDEC spi-nor, declared in a Device Tree, but not
>>> physically present on the board, is involved in a write operation, as:
>>>
>>> cat datafile > /dev/mtd0
>>>
>>> In some cases, with enough quantity of data, the writing hangs for
>> minutes.
>>>
>>> This situation can happen, for example, in some embedded systems, when
>>> a non-JEDEC spi-nor is mounted using a removable add-on board. So is
>>> important to find a method to check a non-JEDEC device presence before
>>> using it.
>>>
>>> The presence of a JEDEC compliant device is implicitly verified during
>> the
>>> JEDEC auto-detect procedure.
>>> But for a non-JEDEC device, the presence must be explicitly checked,
>>> reading one or more known registers, according to the chip features.
>>>
>>> Without any check, if the spi-nor is declared in a Device Tree but not
>>> physically present on the board, the driver (i.e. m25p80) is loaded
>> anyway
>>> and the correspondent mtd device is also created.
>>> In this way any read operation on this device returns 0xff (or 0x00,
>>> depending on the driver and the hardware used) and any write operation
>>> hangs until the flash operation timeout occurs, with the "flash
>> operation
>>> timed out" error message.
>>>
>>> This patch adds the non-JEDEC spi-nor presence check before initializing
>>> the device.
>>>
>>> Note: currently this presence check supports only the Everspin mr25h40,
>>>       reading its status register.
>>>
>>>       The support for other non-JEDEC devices has to be added.
>>>
>>> Signed-off-by: Flavio Suligoi <f.suligoi@xxxxxxx>
>>> ---
>>>  drivers/mtd/spi-nor/spi-nor.c | 43
>> +++++++++++++++++++++++++++++++++++++++++++
>>>  1 file changed, 43 insertions(+)
>>>
>>> diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-
>> nor.c
>>> index fae1474..d2cb710 100644
>>> --- a/drivers/mtd/spi-nor/spi-nor.c
>>> +++ b/drivers/mtd/spi-nor/spi-nor.c
>>> @@ -3981,6 +3981,42 @@ static const struct flash_info
>> *spi_nor_match_id(const char *name)
>>>  	return NULL;
>>>  }
>>>
>>> +/**
>>> + * check_nojedec_nor_presence() - check the real presence of a non-
>> JEDEC nor
>>> + * @nor: pointer to a 'struct spi_nor'
>>> + *
>>> + * The presence of a JEDEC compliant device is implicity verified
>> during the
>>
>> s/implicity/implicitly
>>
>>> + * JEDEC auto-detect procedure.
>>> + * For a non-JEDEC device, the presence have to explicity checked,
>> reading
>>
>> s/explicity/explicitly
>>
>>> + * one or more known registers, according to the chip features.
>>> + *
>>> + * Return: 0 on success, -errno otherwise.
>>> + */
>>> +int check_nojedec_nor_presence(struct spi_nor *nor)
>>
>> all functions should start with spi_nor_*. How about naming it
>> spi_nor_check_nojedec_presence()?
>>
>>> +{
>>> +	struct device *dev = nor->dev;
>>
>> you use dev once, no need to declare a local variable for it.
>>
>>> +	const struct flash_info *info = nor->info;
>>
>> this will probably disappear, see below
>>
>>> +	int ret = 0;
>>
>> initialization not needed
>>
>>> +	u8 val;
>>> +
>>> +	/* Check presence for Everspin mr25h40 MRAM */
>>> +	if (!strcmp(info->name, "mr25h40")) {
>>
>> Couldn't we make this check for all non-jedec flashes? Aren't we safe to
>> assume
>> that all the flashes have a Status Register that contains a WEL bit which
>> come
>> with value zero by default?

Marek, Vignesh, do you know if this assumption is correct?

> 
> I don't know if all the non-JEDEC flashes have a Status Register with
> the same configuration and with the same default values. So for this 
> reason I thought to add a specific test for each single flash.
> In this way, every person who work with a specific flash can add
> a proper flash presence test.
> What do you think about this?

I'm not very happy with having a check for each specific flash, the code will go
nuts in size. Let's do a generic method, like the one I proposed above. If Marek
or Vignesh can not confirm if the assumption is correct, then we will have to
check the datasheets for each non-jedec flash declared in spi-nor to validate
the assumption :(.

ta

> 
>>
>>> +		/* Read the status register */
>>> +		ret = nor->read_reg(nor, SPINOR_OP_RDSR, &val, 1);
>>> +		if (ret)
>>> +			return ret;
>>> +
>>> +		dev_dbg(dev, "%s - status register = 0x%2.2x\n",
>>
>> %hhx?
>>
>>> +			info->name, val);
>>> +
>>> +		/* The factory preset of the status register is 0x00 */
>>
>> if we generalize this, the comment will become irrelevant. How about
>> something
>> like: "Check if flash is connected."
>>
>>> +		if (val == 0xff)
>>> +			return -ENODEV;
>>> +	}
>>> +
>>> +	return 0;
>>> +}
>>> +
>>>  int spi_nor_scan(struct spi_nor *nor, const char *name,
>>>  		 const struct spi_nor_hwcaps *hwcaps)
>>>  {
>>> @@ -4158,6 +4194,13 @@ int spi_nor_scan(struct spi_nor *nor, const char
>> *name,
>>>  			return ret;
>>>  	}
>>>
>>> +	/* Check non-JEDEC nor presence */
>>> +	if (!info->id_len) {
>>
>> if (name && !info->id_len)?
>>
>> How about moving the entire if block to
>> https://elixir.bootlin.com/linux/v5.2-rc6/source/drivers/mtd/spi-nor/spi-
>> nor.c#L4037?
>>
>> Cheers,
>> ta
>>
>>> +		ret = check_nojedec_nor_presence(nor);
>>> +		if (ret)
>>> +			return ret;
>>> +	}
>>> +
>>>  	/* Send all the required SPI flash commands to initialize device */
>>>  	ret = spi_nor_init(nor);
>>>  	if (ret)
>>>
> 
> Thanks,
> Flavio
> 
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/



[Index of Archives]     [LARTC]     [Bugtraq]     [Yosemite Forum]     [Photo]

  Powered by Linux