[PATCH] mtd: spi-nor: use _lock_and_prep() in _read_sfdp()
Cyrille Pitchen
cyrille.pitchen at wedev4u.fr
Fri Dec 22 04:53:35 PST 2017
Le 22/12/2017 à 13:49, Cyrille Pitchen a écrit :
> Hi Yogesh,
>
> Le 22/12/2017 à 09:35, Yogesh Gaur a écrit :
>> spi_nor_read_sfdp() calls nor->read() to read the SFDP data.
>> But first needs to call nor->prepare() to prepare the READ command before
>> calling nor->read().
>>
>
> Currently, I don't agree with this: spi_nor_read_sfdp() is called only from
> spi_nor_scan(). Before the SFDP patch, spi_nor_scan() has already been
> calling for years nor->read_reg() and nor->write_reg() without calling
> spi_nor_lock_and_prep() first.
>
> Indeed, still being in spi_nor_scan(), the SPI NOR memory should have not
> been registered yet to the above MTD layer. So there should be no need to
> lock nor->lock at this point.
>
> Then, about calling nor->prepare(), IMHO, it's look a little bit odd that
s/it's look/it looks/
:p
> neither nor->read_reg() nor nor->write_reg() require nor->prepare() to be
> called first whereas nor->read() does need it.
>
> You didn't describe what issue or bug you actually noticed so now I assume
> it deals with the fsl-quadspi.c driver. So let's have a look at its
> implementation of nor->prepare() / fsl_qspi_prep():
>
> +static int fsl_qspi_prep(struct spi_nor *nor, enum spi_nor_ops ops)
> +{
> + struct fsl_qspi *q = nor->priv;
> + int ret;
> +
> + mutex_lock(&q->lock);
>
> It was not needed before by fsl_qspi_read_reg() or fls_qspi_write_reg(),
> why would it be needed now by fls_qspi_read()?
>
> Then I guess, this is not the issue.
>
> Anyway, if actually needed or safer, the mutex can be locked just after
> mutex_init() and before for_each_available_child_of_node() in
> fsl_qspi_probe().
>
> +
> + ret = fsl_qspi_clk_prep_enable(q);
>
> Already called from fls_qpsi_probe() before calling spi_nor_scan():
> should not be the issue neither.
>
> + if (ret)
> + goto err_mutex;
> +
> + fsl_qspi_set_base_addr(q, nor);
>
> Also called from fsl_qspi_probe() right before calling spi_nor_scan():
>
> /* set the chip address for READID */
> fsl_qspi_set_base_addr(q, nor);
>
> ret = spi_nor_scan(nor, NULL, &hwcaps);
> if (ret)
> goto mutex_failed;
>
> ret = mtd_device_register(mtd, NULL, 0);
> if (ret)
> goto mutex_failed;
>
> /* Set the correct NOR size now. */
> if (q->nor_size == 0) {
> q->nor_size = mtd->size;
>
> /* Map the SPI NOR to accessiable address */
> fsl_qspi_set_map_addr(q);
> }
>
> q->nor_size is only updated after spi_nor_scan() hence I don't see why
> calling nor->prepare() hence fsl_qpsi_set_base_addr() one more time now
> during spi_nor_scan() would actually change anything.
>
> Please note that all I said was based on the assumption that you are trying
> to fix an issue in the fsl-quadspi.c driver (based on your email address:
> @nxp.com) as the nxp-spifi.c driver doesn't provide any implementation for
> the optional nor->prepare().
>
> Then could you please describe a little bit more details about the actual
> issue? What does this patch fix? Which drivers are involved?
>
> Indeed, you would like to have a precise understanding of the issue and
> also avoid modifying spi-nor.c rather than the single fsl-quadspi.c driver
> or whatever driver is concerned since calling nor->preprare() from
> spi_nor_scan() has never been done before and may have unwanted side effects
> on other SPI flash controller drivers.
>
> Actually, this is the reason why spi_nor_read_sfdp() directly calls
> nor->read() instead of spi_nor_read().
>
> Best regards,
>
> Cyrille
>
> + return 0;
> +
> +err_mutex:
> + mutex_unlock(&q->lock);
> + return ret;
> +}
>
>
>> Patch adds call to spi_nor_lock_and_prep() to prepare the READ command
>> and add subsequent call to spi_nor_unlock_and_unprep() to release lock
>> and call nor->unprepare().
>>
>> Signed-off-by: Yogesh Gaur <yogeshnarayan.gaur at nxp.com>
>> ---
>> drivers/mtd/spi-nor/spi-nor.c | 6 ++++++
>> 1 file changed, 6 insertions(+)
>>
>> diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
>> index 2203d6ef..9fb85ae 100644
>> --- a/drivers/mtd/spi-nor/spi-nor.c
>> +++ b/drivers/mtd/spi-nor/spi-nor.c
>> @@ -1807,6 +1807,10 @@ static int spi_nor_read_sfdp(struct spi_nor *nor, u32 addr,
>> nor->addr_width = 3;
>> nor->read_dummy = 8;
>>
>> + ret = spi_nor_lock_and_prep(nor, SPI_NOR_OPS_READ);
>> + if (ret)
>> + goto lock_err;
>> +
>> while (len) {
>> ret = nor->read(nor, addr, len, (u8 *)buf);
>> if (!ret || ret > len) {
>> @@ -1822,6 +1826,8 @@ static int spi_nor_read_sfdp(struct spi_nor *nor, u32 addr,
>> }
>> ret = 0;
>>
>> + spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_READ);
>> +lock_err:
>> read_err:
>> nor->read_opcode = read_opcode;
>> nor->addr_width = addr_width;
>>
>
>
> ______________________________________________________
> Linux MTD discussion mailing list
> http://lists.infradead.org/mailman/listinfo/linux-mtd/
>
More information about the linux-mtd
mailing list