89 lines
3.0 KiB
Diff
89 lines
3.0 KiB
Diff
From 2863ac8e4dd2da305e6b3bbf4e653e57ea36af6b Mon Sep 17 00:00:00 2001
|
|
From: Yicong Yang <yangyicong@hisilicon.com>
|
|
Date: Fri, 17 Apr 2020 15:48:27 +0800
|
|
Subject: [PATCH 29/39] spi: hisi-sfc-v3xx: add error check after per operation
|
|
|
|
mainline inclusion
|
|
from mainline-v5.8-rc1
|
|
commit 59fc9ad5cb108bce18043281c7cf67f2b425d55d
|
|
category: feature
|
|
bugzilla: https://gitee.com/openeuler/kernel/issues/I8CSBP
|
|
CVE: NA
|
|
|
|
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=59fc9ad5cb108bce18043281c7cf67f2b425d55d
|
|
|
|
----------------------------------------------------------------------------
|
|
|
|
The controller may receive instructions of accessing protected address,
|
|
or may perform failed page program. These operations will not succeed
|
|
and the controller will receive interrupts when such failure occur.
|
|
Previously we don't check the interrupts and return 0 even if such
|
|
operation fails.
|
|
|
|
Check the interrupts after per command and inform the user
|
|
if there is an error.
|
|
|
|
Signed-off-by: Yicong Yang <yangyicong@hisilicon.com>
|
|
Acked-by: John Garry <john.garry@huawei.com>
|
|
Link: https://lore.kernel.org/r/1587109707-23597-1-git-send-email-yangyicong@hisilicon.com
|
|
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
Signed-off-by: YunYi Yang <yangyunyi2@huawei.com>
|
|
---
|
|
drivers/spi/spi-hisi-sfc-v3xx.c | 26 +++++++++++++++++++++++++-
|
|
1 file changed, 25 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/drivers/spi/spi-hisi-sfc-v3xx.c b/drivers/spi/spi-hisi-sfc-v3xx.c
|
|
index c46812f004b7..7b90ba2184ac 100644
|
|
--- a/drivers/spi/spi-hisi-sfc-v3xx.c
|
|
+++ b/drivers/spi/spi-hisi-sfc-v3xx.c
|
|
@@ -17,6 +17,11 @@
|
|
|
|
#define HISI_SFC_V3XX_VERSION (0x1f8)
|
|
|
|
+#define HISI_SFC_V3XX_INT_STAT (0x120)
|
|
+#define HISI_SFC_V3XX_INT_STAT_PP_ERR BIT(2)
|
|
+#define HISI_SFC_V3XX_INT_STAT_ADDR_IACCES BIT(5)
|
|
+#define HISI_SFC_V3XX_INT_CLR (0x12c)
|
|
+#define HISI_SFC_V3XX_INT_CLR_CLEAR (0xff)
|
|
#define HISI_SFC_V3XX_CMD_CFG (0x300)
|
|
#define HISI_SFC_V3XX_CMD_CFG_DUAL_IN_DUAL_OUT (1 << 17)
|
|
#define HISI_SFC_V3XX_CMD_CFG_DUAL_IO (2 << 17)
|
|
@@ -163,7 +168,7 @@ static int hisi_sfc_v3xx_generic_exec_op(struct hisi_sfc_v3xx_host *host,
|
|
u8 chip_select)
|
|
{
|
|
int ret, len = op->data.nbytes;
|
|
- u32 config = 0;
|
|
+ u32 int_stat, config = 0;
|
|
|
|
if (op->addr.nbytes)
|
|
config |= HISI_SFC_V3XX_CMD_CFG_ADDR_EN_MSK;
|
|
@@ -224,6 +229,25 @@ static int hisi_sfc_v3xx_generic_exec_op(struct hisi_sfc_v3xx_host *host,
|
|
if (ret)
|
|
return ret;
|
|
|
|
+ /*
|
|
+ * The interrupt status register indicates whether an error occurs
|
|
+ * after per operation. Check it, and clear the interrupts for
|
|
+ * next time judgement.
|
|
+ */
|
|
+ int_stat = readl(host->regbase + HISI_SFC_V3XX_INT_STAT);
|
|
+ writel(HISI_SFC_V3XX_INT_CLR_CLEAR,
|
|
+ host->regbase + HISI_SFC_V3XX_INT_CLR);
|
|
+
|
|
+ if (int_stat & HISI_SFC_V3XX_INT_STAT_ADDR_IACCES) {
|
|
+ dev_err(host->dev, "fail to access protected address\n");
|
|
+ return -EIO;
|
|
+ }
|
|
+
|
|
+ if (int_stat & HISI_SFC_V3XX_INT_STAT_PP_ERR) {
|
|
+ dev_err(host->dev, "page program operation failed\n");
|
|
+ return -EIO;
|
|
+ }
|
|
+
|
|
if (op->data.dir == SPI_MEM_DATA_IN)
|
|
hisi_sfc_v3xx_read_databuf(host, op->data.buf.in, len);
|
|
|
|
--
|
|
2.27.0
|
|
|