[PATCH v2 3/3] mtd: spi-nor: Add clear flag status register support
Jonas Gorski
jogo at openwrt.org
Sat Sep 12 11:57:26 PDT 2015
On Wed, Aug 26, 2015 at 12:48 PM, Jagan Teki <jteki at openedev.com> wrote:
> The clear flag status register operation is required by Micron
> SPI-NOR chips, which support FSR. And if error bits of FSR
> have been set like protection, voltage, erase, and program,
> it must be cleared by executing clear FSR operation.
>
> Signed-off-by: Jagan Teki <jteki at openedev.com>
> Cc: Hou Zhiqiang <B48286 at freescale.com>
> Cc: Mingkai.Hu <Mingkai.Hu at freescale.com>
> Cc: David Woodhouse <dwmw2 at infradead.org>
> Cc: Brian Norris <computersforpeace at gmail.com>
> ---
> Changes for v2:
> - Write cfsr instead of reading it.
> - Return -EINVAL instead of -1
>
> drivers/mtd/spi-nor/spi-nor.c | 23 +++++++++++++++++++----
> include/linux/mtd/spi-nor.h | 9 +++++++++
> 2 files changed, 28 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
> index f954d03..0a77061 100644
> --- a/drivers/mtd/spi-nor/spi-nor.c
> +++ b/drivers/mtd/spi-nor/spi-nor.c
> @@ -163,6 +163,18 @@ static inline int write_disable(struct spi_nor *nor)
> return nor->write_reg(nor, SPINOR_OP_WRDI, NULL, 0);
> }
>
> +/*
> + * The clear flag status register operation is required by Micron
> + * SPI-NOR chips, which support FSR. And if error bits of FSR
> + * have been set like protection, voltage, erase, and program,
> + * it must be cleared by executing clear FSR operation.
> + * Returns negative if error occurred.
> + */
> +static inline int write_cfsr(struct spi_nor *nor)
> +{
> + return nor->write_reg(nor, SPINOR_OP_WRCFSR, NULL, 0);
> +}
> +
> static inline struct spi_nor *mtd_to_spi_nor(struct mtd_info *mtd)
> {
> return mtd->priv;
> @@ -209,10 +221,13 @@ static inline int spi_nor_sr_ready(struct spi_nor *nor)
> static inline int spi_nor_fsr_ready(struct spi_nor *nor)
> {
> int fsr = read_fsr(nor);
> - if (fsr < 0)
> - return fsr;
While it's rather unlikely that read_fsr() will return -EBFONT (which
has neither of the FSR_ERR_MASK bits set), you should keep the check
for negative return value intact.
> - else
> - return fsr & FSR_READY;
> + if (fsr & FSR_ERR_MASK) {
Also the N25Q032 data sheet says that these bits are only valid if
FSR_READY is set. so you should bail out early if it isn't, and check
the error bits only if it is set.
> + pr_err("flag status(0x%x) error occured\n", fsr);
I suggest using a better error message than "flag status() error
occured" and maybe even decode the error bits, so it's obvious what
kind of error is there without looking at the #defines or a data
sheet. Not sure about a better wording though, "last operation failed
for the following reason:%s%s%s\n", fsr & FSR_ERR_PROT ? " PROT" :
"", fsr & ...
> + write_cfsr(nor);
I'm not sure if a is_ready() function should clear the error bits, and
rather the functions that can cause these to be set should be made
aware of it and checking them (and then cleaning them), but maybe that
would require a rewrite how some functions are done.
> + return -EINVAL;
Also I wonder if there are more appropriate error values here than
-EINVAL, e.g. -EPERM if FSR_ERR_PROT is set, else -EIO if
FSR_ERR_ERASE or FSR_ERR_PROG are set.
> + }
> +
> + return fsr & FSR_READY;
> }
Jonas
More information about the linux-mtd
mailing list