[linux-yocto][linux-yocto v5.15] kernel code for marvell cn96xx

2023-07-11 Thread Ruiqiang Hao via lists.yoctoproject.org
Hi Bruce,

This patch is for Cypress flash s25fl064l used by customer.
Please help to merge this patch into our linux-yocto repo.

repo:
linux-yocto
branch:
v5.15/standard/cn-sdkv5.4/octeon
v5.15/standard/preempt-rt/cn-sdkv5.4/octeon

Thanks,
Ruiqiang

-=-=-=-=-=-=-=-=-=-=-=-
Links: You receive all messages sent to this group.
View/Reply Online (#12847): 
https://lists.yoctoproject.org/g/linux-yocto/message/12847
Mute This Topic: https://lists.yoctoproject.org/mt/100094135/21656
Group Owner: linux-yocto+ow...@lists.yoctoproject.org
Unsubscribe: https://lists.yoctoproject.org/g/linux-yocto/unsub 
[arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-



[linux-yocto] [PATCH] mtd: spi-nor: Use CLSR command for FL-L chips

2023-07-11 Thread Ruiqiang Hao via lists.yoctoproject.org
From: Yaliang Wang 

S25FL{064|128|256}L chips can't recover from errors, when there are
program error or erase error, P_ERR or E_ERR bit will set to one, WIP
bit will remain set to one, A Clear Status Register command must be sent
to return the device to STANDBY state.

The error first recorded in commit  ("mtd: spi-nor: Recover
from Spansion/Cypress errors"). Whlie FL-L chips shifted P_ERR or E_ERR
bits to Status Register 2, which causing the current recover process
doesn't work any more after enabling using CLSR.

Signed-off-by: Yaliang Wang 
Upstream-Status: Backport [Wind River Case 00112304]
Signed-off-by: Kalle Pirinen 
Signed-off-by: Ruqiang Hao 
---
 drivers/mtd/spi-nor/core.c | 91 +-
 1 file changed, 71 insertions(+), 20 deletions(-)

diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index b87d11c54b2a..c94e2389b8aa 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -677,37 +677,85 @@ static void spi_nor_clear_sr(struct spi_nor *nor)
 }
 
 static const struct flash_info *spi_nor_read_id(struct spi_nor *nor);
+
+/**
+ * spi_nor_s25fl_l_read_sr2() - Read the Status Register 2 using the
+ * SPINOR_OP_RDSR2_FL_L (07h) command.
+ * @nor:   pointer to 'struct spi_nor'.
+ * @sr2:   pointer to DMA-able buffer where the value of the
+ * Status Register 2 will be written.
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
+static int spi_nor_s25fl_l_read_sr2(struct spi_nor *nor, u8 *sr2)
+{
+   int ret;
+
+   if (nor->spimem) {
+   struct spi_mem_op op =
+   SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RDSR2_FL_L, 1),
+  SPI_MEM_OP_NO_ADDR,
+  SPI_MEM_OP_NO_DUMMY,
+  SPI_MEM_OP_DATA_IN(1, sr2, 1));
+
+   ret = spi_mem_exec_op(nor->spimem, );
+   } else {
+   ret = nor->controller_ops->read_reg(nor, SPINOR_OP_RDSR2_FL_L,
+   sr2, 1);
+   }
+
+   if (ret)
+   dev_dbg(nor->dev, "error %d reading SR2\n", ret);
+
+   return ret;
+}
+
 /*
- * Cypress FL-L series devices have redesigned the status register,
- * P_ERR and E_ERR bits are shifted to the status register 2.
+ * spi_nor_s25fl_l_sr_ready() - Query the Status Register to see if the flash
+ * is ready for new commands. Used by Cypress FL-L series chips.
+ * @nor:   pointer to 'struct spi_nor'.
+ *
+ * Return: 1 if ready, 0 if not ready, -errno on errors.
  */
 static int spi_nor_s25fl_l_sr_ready(struct spi_nor *nor)
 {
-   u8 sr1, sr2;
+   u8 *sr = nor->bouncebuf;
int ret;
 
-   ret = nor->controller_ops->read_reg(nor, SPINOR_OP_RDSR, , 1);
-   if (ret < 0) {
-   pr_err("error %d reading SR\n", (int) ret);
+   ret = spi_nor_read_sr(nor, sr);
+   if (ret)
return ret;
-   }
-   ret = nor->controller_ops->read_reg(nor, SPINOR_OP_RDSR2_FL_L, , 1);
-   if (ret < 0) {
-   pr_err("error %d reading SR2\n", (int) ret);
+
+   /**
+* P_ERR and E_ERR bits are located in the Status Register 2
+* of Cypress FL-L series chips.
+*/
+   ret = spi_nor_s25fl_l_read_sr2(nor, [1]);
+   if (ret)
return ret;
-   }
 
-   if (nor->flags & SNOR_F_USE_CLSR && sr2 & (SR_E_ERR | SR_P_ERR)) {
-   if (sr2 & SR_E_ERR)
+   if (nor->flags & SNOR_F_USE_CLSR && sr[1] & (SR_E_ERR | SR_P_ERR)) {
+   if (sr[1] & SR_E_ERR)
dev_err(nor->dev, "Erase Error occurred\n");
else
dev_err(nor->dev, "Programming Error occurred\n");
 
-   nor->controller_ops->write_reg(nor, SPINOR_OP_CLSR, NULL, 0);
+   spi_nor_clear_sr(nor);
+
+   /*
+* WEL bit remains set to one when an erase or page program
+* error occurs. Issue a Write Disable command to protect
+* against inadvertent writes that can possibly corrupt the
+* contents of the memory.
+*/
+   ret = spi_nor_write_disable(nor);
+   if (ret)
+   return ret;
+
return -EIO;
}
 
-   return !(sr1 & SR_WIP);
+   return !(sr[0] & SR_WIP);
 }
 
 /**
@@ -720,12 +768,15 @@ static int spi_nor_s25fl_l_sr_ready(struct spi_nor *nor)
 static int spi_nor_sr_ready(struct spi_nor *nor)
 {
int ret;
-   const struct flash_info *tmpinfo = (nor->info == NULL) ? nor->info : 
spi_nor_read_id(nor);
+   const struct flash_info *tmpinfo = nor->info ? nor->info : 
spi_nor_read_id(nor);
 
-   if (!IS_ERR_OR_NULL(tmpinfo)){
-   if (!strcmp(tmpinfo->name, "s25fl064l") || 
!strcmp(tmpinfo->name, "s25fl128l") || !strcmp(tmpinfo->name, "s25fl256l")){
-   return spi_nor_s25fl_l_sr_ready(nor);
-