linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 3/3] mtd: spi-nor: Add clear flag status register support
@ 2015-08-26 10:48 Jagan Teki
  2015-09-01 16:10 ` Jagan Teki
  2015-09-12 18:57 ` Jonas Gorski
  0 siblings, 2 replies; 4+ messages in thread
From: Jagan Teki @ 2015-08-26 10:48 UTC (permalink / raw)
  To: linux-mtd
  Cc: linux-kernel, Jagan Teki, Hou Zhiqiang, Mingkai.Hu,
	David Woodhouse, Brian Norris

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@openedev.com>
Cc: Hou Zhiqiang <B48286@freescale.com>
Cc: Mingkai.Hu <Mingkai.Hu@freescale.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Cc: Brian Norris <computersforpeace@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;
-	else
-		return fsr & FSR_READY;
+	if (fsr & FSR_ERR_MASK) {
+		pr_err("flag status(0x%x) error occured\n", fsr);
+		write_cfsr(nor);
+		return -EINVAL;
+	}
+
+	return fsr & FSR_READY;
 }
 
 static int spi_nor_ready(struct spi_nor *nor)
diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
index c5a58c4..0288081 100644
--- a/include/linux/mtd/spi-nor.h
+++ b/include/linux/mtd/spi-nor.h
@@ -35,6 +35,7 @@
 #define SPINOR_OP_RDID		0x9f	/* Read JEDEC ID */
 #define SPINOR_OP_RDCR		0x35	/* Read configuration register */
 #define SPINOR_OP_RDFSR		0x70	/* Read flag status register */
+#define SPINOR_OP_WRCFSR	0x50	/* Write clear flag status register */
 
 /* 4-byte address opcodes - used on Spansion and some Macronix flashes. */
 #define SPINOR_OP_READ4		0x13	/* Read data bytes (low frequency) */
@@ -74,6 +75,14 @@
 /* Enhanced Volatile Configuration Register bits */
 #define EVCR_QUAD_EN_MICRON    0x80    /* Micron Quad I/O */
 
+/* Flag Status Register Error bits */
+#define FSR_ERR_PROT		0x2	/* Protection */
+#define FSR_ERR_VOLT		0x8	/* Voltage on Vpp */
+#define FSR_ERR_PROG		0x10	/* Program operation */
+#define FSR_ERR_ERASE		0x20	/* Erase operation */
+#define FSR_ERR_MASK		(FSR_ERR_PROT | FSR_ERR_VOLT | \
+				FSR_ERR_PROG | FSR_ERR_ERASE)
+
 /* Flag Status Register bits */
 #define FSR_READY		0x80
 
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH v2 3/3] mtd: spi-nor: Add clear flag status register support
  2015-08-26 10:48 [PATCH v2 3/3] mtd: spi-nor: Add clear flag status register support Jagan Teki
@ 2015-09-01 16:10 ` Jagan Teki
  2015-09-12 16:07   ` Jagan Teki
  2015-09-12 18:57 ` Jonas Gorski
  1 sibling, 1 reply; 4+ messages in thread
From: Jagan Teki @ 2015-09-01 16:10 UTC (permalink / raw)
  To: linux-mtd
  Cc: linux-kernel, Jagan Teki, Hou Zhiqiang, Mingkai.Hu,
	David Woodhouse, Brian Norris

On 26 August 2015 at 16:18, Jagan Teki <jteki@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@openedev.com>
> Cc: Hou Zhiqiang <B48286@freescale.com>
> Cc: Mingkai.Hu <Mingkai.Hu@freescale.com>
> Cc: David Woodhouse <dwmw2@infradead.org>
> Cc: Brian Norris <computersforpeace@gmail.com>

Any response, please comment

> ---
> 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;
> -       else
> -               return fsr & FSR_READY;
> +       if (fsr & FSR_ERR_MASK) {
> +               pr_err("flag status(0x%x) error occured\n", fsr);
> +               write_cfsr(nor);
> +               return -EINVAL;
> +       }
> +
> +       return fsr & FSR_READY;
>  }
>
>  static int spi_nor_ready(struct spi_nor *nor)
> diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
> index c5a58c4..0288081 100644
> --- a/include/linux/mtd/spi-nor.h
> +++ b/include/linux/mtd/spi-nor.h
> @@ -35,6 +35,7 @@
>  #define SPINOR_OP_RDID         0x9f    /* Read JEDEC ID */
>  #define SPINOR_OP_RDCR         0x35    /* Read configuration register */
>  #define SPINOR_OP_RDFSR                0x70    /* Read flag status register */
> +#define SPINOR_OP_WRCFSR       0x50    /* Write clear flag status register */
>
>  /* 4-byte address opcodes - used on Spansion and some Macronix flashes. */
>  #define SPINOR_OP_READ4                0x13    /* Read data bytes (low frequency) */
> @@ -74,6 +75,14 @@
>  /* Enhanced Volatile Configuration Register bits */
>  #define EVCR_QUAD_EN_MICRON    0x80    /* Micron Quad I/O */
>
> +/* Flag Status Register Error bits */
> +#define FSR_ERR_PROT           0x2     /* Protection */
> +#define FSR_ERR_VOLT           0x8     /* Voltage on Vpp */
> +#define FSR_ERR_PROG           0x10    /* Program operation */
> +#define FSR_ERR_ERASE          0x20    /* Erase operation */
> +#define FSR_ERR_MASK           (FSR_ERR_PROT | FSR_ERR_VOLT | \
> +                               FSR_ERR_PROG | FSR_ERR_ERASE)
> +
>  /* Flag Status Register bits */
>  #define FSR_READY              0x80
>
> --
> 1.9.1
>

thanks!
-- 
Jagan.

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH v2 3/3] mtd: spi-nor: Add clear flag status register support
  2015-09-01 16:10 ` Jagan Teki
@ 2015-09-12 16:07   ` Jagan Teki
  0 siblings, 0 replies; 4+ messages in thread
From: Jagan Teki @ 2015-09-12 16:07 UTC (permalink / raw)
  To: linux-mtd
  Cc: linux-kernel, Jagan Teki, Hou Zhiqiang, Mingkai.Hu,
	David Woodhouse, Brian Norris

On 1 September 2015 at 21:40, Jagan Teki <jteki@openedev.com> wrote:
> On 26 August 2015 at 16:18, Jagan Teki <jteki@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@openedev.com>
>> Cc: Hou Zhiqiang <B48286@freescale.com>
>> Cc: Mingkai.Hu <Mingkai.Hu@freescale.com>
>> Cc: David Woodhouse <dwmw2@infradead.org>
>> Cc: Brian Norris <computersforpeace@gmail.com>
>
> Any response, please comment
>
>> ---
>> 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;
>> -       else
>> -               return fsr & FSR_READY;
>> +       if (fsr & FSR_ERR_MASK) {
>> +               pr_err("flag status(0x%x) error occured\n", fsr);
>> +               write_cfsr(nor);
>> +               return -EINVAL;
>> +       }
>> +
>> +       return fsr & FSR_READY;
>>  }
>>
>>  static int spi_nor_ready(struct spi_nor *nor)
>> diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
>> index c5a58c4..0288081 100644
>> --- a/include/linux/mtd/spi-nor.h
>> +++ b/include/linux/mtd/spi-nor.h
>> @@ -35,6 +35,7 @@
>>  #define SPINOR_OP_RDID         0x9f    /* Read JEDEC ID */
>>  #define SPINOR_OP_RDCR         0x35    /* Read configuration register */
>>  #define SPINOR_OP_RDFSR                0x70    /* Read flag status register */
>> +#define SPINOR_OP_WRCFSR       0x50    /* Write clear flag status register */
>>
>>  /* 4-byte address opcodes - used on Spansion and some Macronix flashes. */
>>  #define SPINOR_OP_READ4                0x13    /* Read data bytes (low frequency) */
>> @@ -74,6 +75,14 @@
>>  /* Enhanced Volatile Configuration Register bits */
>>  #define EVCR_QUAD_EN_MICRON    0x80    /* Micron Quad I/O */
>>
>> +/* Flag Status Register Error bits */
>> +#define FSR_ERR_PROT           0x2     /* Protection */
>> +#define FSR_ERR_VOLT           0x8     /* Voltage on Vpp */
>> +#define FSR_ERR_PROG           0x10    /* Program operation */
>> +#define FSR_ERR_ERASE          0x20    /* Erase operation */
>> +#define FSR_ERR_MASK           (FSR_ERR_PROT | FSR_ERR_VOLT | \
>> +                               FSR_ERR_PROG | FSR_ERR_ERASE)
>> +
>>  /* Flag Status Register bits */
>>  #define FSR_READY              0x80
>>
>> --
>> 1.9.1

Ping!

thanks!
-- 
Jagan | openedev.

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH v2 3/3] mtd: spi-nor: Add clear flag status register support
  2015-08-26 10:48 [PATCH v2 3/3] mtd: spi-nor: Add clear flag status register support Jagan Teki
  2015-09-01 16:10 ` Jagan Teki
@ 2015-09-12 18:57 ` Jonas Gorski
  1 sibling, 0 replies; 4+ messages in thread
From: Jonas Gorski @ 2015-09-12 18:57 UTC (permalink / raw)
  To: Jagan Teki
  Cc: MTD Maling List, Hou Zhiqiang, linux-kernel, Mingkai.Hu,
	Brian Norris, David Woodhouse

On Wed, Aug 26, 2015 at 12:48 PM, Jagan Teki <jteki@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@openedev.com>
> Cc: Hou Zhiqiang <B48286@freescale.com>
> Cc: Mingkai.Hu <Mingkai.Hu@freescale.com>
> Cc: David Woodhouse <dwmw2@infradead.org>
> Cc: Brian Norris <computersforpeace@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

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2015-09-12 18:58 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-08-26 10:48 [PATCH v2 3/3] mtd: spi-nor: Add clear flag status register support Jagan Teki
2015-09-01 16:10 ` Jagan Teki
2015-09-12 16:07   ` Jagan Teki
2015-09-12 18:57 ` Jonas Gorski

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).