259 lines
7.5 KiB
Diff
259 lines
7.5 KiB
Diff
From b5eb1d02d31155f46aab15b435f9bff0a2e83097 Mon Sep 17 00:00:00 2001
|
|
From: Tudor Ambarus <tudor.ambarus@microchip.com>
|
|
Date: Thu, 24 Oct 2019 15:55:34 +0300
|
|
Subject: [PATCH 08/39] mtd: spi-nor: Pointer parameter for SR in
|
|
spi_nor_read_sr()
|
|
|
|
mainline inclusion
|
|
from mainline-v5.5-rc1
|
|
commit cd1718f5c49d53539c99f45a485ca0e0ac7f0a99
|
|
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=cd1718f5c49d53539c99f45a485ca0e0ac7f0a99
|
|
|
|
----------------------------------------------------------------------------
|
|
|
|
Let the callers pass the pointer to the DMA-able buffer where
|
|
the value of the Status Register will be written. This way we
|
|
avoid the casts between int and u8, which can be confusing.
|
|
|
|
Callers stop compare the return value of spi_nor_read_sr() with negative,
|
|
spi_nor_read_sr() returns 0 on success and -errno otherwise.
|
|
|
|
Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
|
|
Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
|
|
Signed-off-by: YunYi Yang <yangyunyi2@huawei.com>
|
|
|
|
Conflicts:
|
|
drivers/mtd/spi-nor/spi-nor.c
|
|
---
|
|
drivers/mtd/spi-nor/spi-nor.c | 101 ++++++++++++++++++----------------
|
|
1 file changed, 55 insertions(+), 46 deletions(-)
|
|
|
|
diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
|
|
index 0c9f58d8819c..3a10b5939cd2 100644
|
|
--- a/drivers/mtd/spi-nor/spi-nor.c
|
|
+++ b/drivers/mtd/spi-nor/spi-nor.c
|
|
@@ -246,12 +246,15 @@ static ssize_t spi_nor_write_data(struct spi_nor *nor, loff_t to, size_t len,
|
|
return nor->write(nor, to, len, buf);
|
|
}
|
|
|
|
-/*
|
|
- * Read the status register, returning its value in the location
|
|
- * Return the status register value.
|
|
- * Returns negative if error occurred.
|
|
+/**
|
|
+ * spi_nor_read_sr() - Read the Status Register.
|
|
+ * @nor: pointer to 'struct spi_nor'.
|
|
+ * @sr: pointer to a DMA-able buffer where the value of the
|
|
+ * Status Register will be written.
|
|
+ *
|
|
+ * Return: 0 on success, -errno otherwise.
|
|
*/
|
|
-static int spi_nor_read_sr(struct spi_nor *nor)
|
|
+static int spi_nor_read_sr(struct spi_nor *nor, u8 *sr)
|
|
{
|
|
int ret;
|
|
|
|
@@ -260,19 +263,17 @@ static int spi_nor_read_sr(struct spi_nor *nor)
|
|
SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RDSR, 1),
|
|
SPI_MEM_OP_NO_ADDR,
|
|
SPI_MEM_OP_NO_DUMMY,
|
|
- SPI_MEM_OP_DATA_IN(1, nor->bouncebuf, 1));
|
|
+ SPI_MEM_OP_DATA_IN(1, sr, 1));
|
|
|
|
ret = spi_mem_exec_op(nor->spimem, &op);
|
|
} else {
|
|
- ret = nor->read_reg(nor, SPINOR_OP_RDSR, nor->bouncebuf, 1);
|
|
+ ret = nor->read_reg(nor, SPINOR_OP_RDSR, sr, 1);
|
|
}
|
|
|
|
- if (ret) {
|
|
+ if (ret)
|
|
pr_err("error %d reading SR\n", (int) ret);
|
|
- return ret;
|
|
- }
|
|
|
|
- return nor->bouncebuf[0];
|
|
+ return ret;
|
|
}
|
|
|
|
/*
|
|
@@ -609,12 +610,14 @@ static int spi_nor_clear_sr(struct spi_nor *nor)
|
|
|
|
static inline int spi_nor_sr_ready(struct spi_nor *nor)
|
|
{
|
|
- int sr = spi_nor_read_sr(nor);
|
|
- if (sr < 0)
|
|
- return sr;
|
|
+ int ret = spi_nor_read_sr(nor, nor->bouncebuf);
|
|
|
|
- if (nor->flags & SNOR_F_USE_CLSR && sr & (SR_E_ERR | SR_P_ERR)) {
|
|
- if (sr & SR_E_ERR)
|
|
+ if (ret)
|
|
+ return ret;
|
|
+
|
|
+ if (nor->flags & SNOR_F_USE_CLSR &&
|
|
+ nor->bouncebuf[0] & (SR_E_ERR | SR_P_ERR)) {
|
|
+ if (nor->bouncebuf[0] & SR_E_ERR)
|
|
dev_err(nor->dev, "Erase Error occurred\n");
|
|
else
|
|
dev_err(nor->dev, "Programming Error occurred\n");
|
|
@@ -623,7 +626,7 @@ static inline int spi_nor_sr_ready(struct spi_nor *nor)
|
|
return -EIO;
|
|
}
|
|
|
|
- return !(sr & SR_WIP);
|
|
+ return !(nor->bouncebuf[0] & SR_WIP);
|
|
}
|
|
|
|
static int spi_nor_clear_fsr(struct spi_nor *nor)
|
|
@@ -914,8 +917,8 @@ static int spi_nor_write_sr_and_check(struct spi_nor *nor, u8 status_new,
|
|
if (ret)
|
|
return ret;
|
|
|
|
- ret = spi_nor_read_sr(nor);
|
|
- if (ret < 0)
|
|
+ ret = spi_nor_read_sr(nor, nor->bouncebuf);
|
|
+ if (ret)
|
|
return ret;
|
|
|
|
return ((ret & mask) != (status_new & mask)) ? -EIO : 0;
|
|
@@ -1013,16 +1016,18 @@ static int stm_is_unlocked_sr(struct spi_nor *nor, loff_t ofs, uint64_t len,
|
|
static int stm_lock(struct spi_nor *nor, loff_t ofs, uint64_t len)
|
|
{
|
|
struct mtd_info *mtd = &nor->mtd;
|
|
- int status_old, status_new;
|
|
+ int ret, status_old, status_new;
|
|
u8 mask = SR_BP2 | SR_BP1 | SR_BP0;
|
|
u8 shift = ffs(mask) - 1, pow, val;
|
|
loff_t lock_len;
|
|
bool can_be_top = true, can_be_bottom = nor->flags & SNOR_F_HAS_SR_TB;
|
|
bool use_top;
|
|
|
|
- status_old = spi_nor_read_sr(nor);
|
|
- if (status_old < 0)
|
|
- return status_old;
|
|
+ ret = spi_nor_read_sr(nor, nor->bouncebuf);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+
|
|
+ status_old = nor->bouncebuf[0];
|
|
|
|
/* If nothing in our range is unlocked, we don't need to do anything */
|
|
if (stm_is_locked_sr(nor, ofs, len, status_old))
|
|
@@ -1093,16 +1098,18 @@ static int stm_lock(struct spi_nor *nor, loff_t ofs, uint64_t len)
|
|
static int stm_unlock(struct spi_nor *nor, loff_t ofs, uint64_t len)
|
|
{
|
|
struct mtd_info *mtd = &nor->mtd;
|
|
- int status_old, status_new;
|
|
+ int ret, status_old, status_new;
|
|
u8 mask = SR_BP2 | SR_BP1 | SR_BP0;
|
|
u8 shift = ffs(mask) - 1, pow, val;
|
|
loff_t lock_len;
|
|
bool can_be_top = true, can_be_bottom = nor->flags & SNOR_F_HAS_SR_TB;
|
|
bool use_top;
|
|
|
|
- status_old = spi_nor_read_sr(nor);
|
|
- if (status_old < 0)
|
|
- return status_old;
|
|
+ ret = spi_nor_read_sr(nor, nor->bouncebuf);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+
|
|
+ status_old = nor->bouncebuf[0];
|
|
|
|
/* If nothing in our range is locked, we don't need to do anything */
|
|
if (stm_is_unlocked_sr(nor, ofs, len, status_old))
|
|
@@ -1177,13 +1184,13 @@ static int stm_unlock(struct spi_nor *nor, loff_t ofs, uint64_t len)
|
|
*/
|
|
static int stm_is_locked(struct spi_nor *nor, loff_t ofs, uint64_t len)
|
|
{
|
|
- int status;
|
|
+ int ret;
|
|
|
|
- status = spi_nor_read_sr(nor);
|
|
- if (status < 0)
|
|
- return status;
|
|
+ ret = spi_nor_read_sr(nor, nor->bouncebuf);
|
|
+ if (ret)
|
|
+ return ret;
|
|
|
|
- return stm_is_locked_sr(nor, ofs, len, status);
|
|
+ return stm_is_locked_sr(nor, ofs, len, nor->bouncebuf[0]);
|
|
}
|
|
|
|
static int spi_nor_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
|
|
@@ -1857,24 +1864,28 @@ static int spi_nor_write(struct mtd_info *mtd, loff_t to, size_t len,
|
|
*/
|
|
static int macronix_quad_enable(struct spi_nor *nor)
|
|
{
|
|
- int ret, val;
|
|
+ int ret;
|
|
|
|
- val = spi_nor_read_sr(nor);
|
|
- if (val < 0)
|
|
- return val;
|
|
- if (val & SR_QUAD_EN_MX)
|
|
+ ret = spi_nor_read_sr(nor, nor->bouncebuf);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+
|
|
+ if (nor->bouncebuf[0] & SR_QUAD_EN_MX)
|
|
return 0;
|
|
|
|
spi_nor_write_enable(nor);
|
|
|
|
- spi_nor_write_sr(nor, val | SR_QUAD_EN_MX);
|
|
+ spi_nor_write_sr(nor, nor->bouncebuf[0] | SR_QUAD_EN_MX);
|
|
|
|
ret = spi_nor_wait_till_ready(nor);
|
|
if (ret)
|
|
return ret;
|
|
|
|
- ret = spi_nor_read_sr(nor);
|
|
- if (!(ret > 0 && (ret & SR_QUAD_EN_MX))) {
|
|
+ ret = spi_nor_read_sr(nor, nor->bouncebuf);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+
|
|
+ if (!(nor->bouncebuf[0] & SR_QUAD_EN_MX)) {
|
|
dev_err(nor->dev, "Macronix Quad bit not set\n");
|
|
return -EINVAL;
|
|
}
|
|
@@ -1986,12 +1997,11 @@ static int spansion_no_read_cr_quad_enable(struct spi_nor *nor)
|
|
int ret;
|
|
|
|
/* Keep the current value of the Status Register. */
|
|
- ret = spi_nor_read_sr(nor);
|
|
- if (ret < 0) {
|
|
+ ret = spi_nor_read_sr(nor, sr_cr);
|
|
+ if (ret) {
|
|
dev_err(nor->dev, "error while reading status register\n");
|
|
return -EINVAL;
|
|
}
|
|
- sr_cr[0] = ret;
|
|
sr_cr[1] = CR_QUAD_EN_SPAN;
|
|
|
|
return spi_nor_write_sr_cr(nor, sr_cr);
|
|
@@ -2029,12 +2039,11 @@ static int spansion_read_cr_quad_enable(struct spi_nor *nor)
|
|
sr_cr[1] = ret | CR_QUAD_EN_SPAN;
|
|
|
|
/* Keep the current value of the Status Register. */
|
|
- ret = spi_nor_read_sr(nor);
|
|
- if (ret < 0) {
|
|
+ ret = spi_nor_read_sr(nor, sr_cr);
|
|
+ if (ret) {
|
|
dev_err(dev, "error while reading status register\n");
|
|
return -EINVAL;
|
|
}
|
|
- sr_cr[0] = ret;
|
|
|
|
ret = spi_nor_write_sr_cr(nor, sr_cr);
|
|
if (ret)
|
|
--
|
|
2.27.0
|
|
|