[RFC PATCH 6/8] mtd: spi-nor: Prepare the introduction of a new locking mechanism
Miquel Raynal
miquel.raynal at bootlin.com
Wed May 25 09:31:06 PDT 2022
This commit alone just introduces two new "lock and prepare" pairs of
helpers which do the exact same thing as before. They will soon be
improved in a followup commit which actually brings the logic, but I
figured out it was more readable to do it this way.
One new pair is suffixed _pe which stands for "program and erase" and
hence is being called by spi_nor_write() and spi_nor_erase().
The other pair is suffixed _rd which stands for "read" and hence is
being called by spi_nor_read().
One note however, these extra helpers will need to know the operation
range, so they come with two new parameters to define it. Otherwise
there is no functional change.
Signed-off-by: Miquel Raynal <miquel.raynal at bootlin.com>
---
drivers/mtd/spi-nor/core.c | 57 ++++++++++++++++++++++++++++++++++----
1 file changed, 51 insertions(+), 6 deletions(-)
diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index 048665252a80..3d8e5f9961b9 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -1081,6 +1081,7 @@ static void spi_nor_unprep(struct spi_nor *nor)
nor->controller_ops->unprepare(nor);
}
+/* Generic helpers for internal locking and serialization */
int spi_nor_lock_and_prep(struct spi_nor *nor)
{
int ret;
@@ -1101,6 +1102,48 @@ void spi_nor_unlock_and_unprep(struct spi_nor *nor)
spi_nor_unprep(nor);
}
+/* Internal locking helpers for program and erase operations */
+static int spi_nor_lock_and_prep_pe(struct spi_nor *nor, loff_t start, size_t len)
+{
+ int ret;
+
+ ret = spi_nor_prep(nor);
+ if (ret)
+ return ret;
+
+ mutex_lock(&nor->lock);
+
+ return 0;
+}
+
+static void spi_nor_unlock_and_unprep_pe(struct spi_nor *nor, loff_t start, size_t len)
+{
+ mutex_unlock(&nor->lock);
+
+ spi_nor_unprep(nor);
+}
+
+/* Internal locking helpers for read operations */
+static int spi_nor_lock_and_prep_rd(struct spi_nor *nor, loff_t start, size_t len)
+{
+ int ret;
+
+ ret = spi_nor_prep(nor);
+ if (ret)
+ return ret;
+
+ mutex_lock(&nor->lock);
+
+ return 0;
+}
+
+static void spi_nor_unlock_and_unprep_rd(struct spi_nor *nor, loff_t start, size_t len)
+{
+ mutex_unlock(&nor->lock);
+
+ spi_nor_unprep(nor);
+}
+
static u32 spi_nor_convert_addr(struct spi_nor *nor, loff_t addr)
{
if (!nor->params->convert_addr)
@@ -1454,7 +1497,7 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr)
addr = instr->addr;
len = instr->len;
- ret = spi_nor_lock_and_prep(nor);
+ ret = spi_nor_lock_and_prep_pe(nor, addr, len);
if (ret)
return ret;
@@ -1517,7 +1560,7 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr)
ret = spi_nor_write_disable(nor);
erase_err:
- spi_nor_unlock_and_unprep(nor);
+ spi_nor_unlock_and_unprep_pe(nor, addr, len);
return ret;
}
@@ -1704,7 +1747,7 @@ static int spi_nor_read(struct mtd_info *mtd, loff_t from, size_t len,
dev_dbg(nor->dev, "from 0x%08x, len %zd\n", (u32)from, len);
- ret = spi_nor_lock_and_prep(nor);
+ ret = spi_nor_lock_and_prep_rd(nor, from, len);
if (ret)
return ret;
@@ -1731,7 +1774,8 @@ static int spi_nor_read(struct mtd_info *mtd, loff_t from, size_t len,
ret = 0;
read_err:
- spi_nor_unlock_and_unprep(nor);
+ spi_nor_unlock_and_unprep_rd(nor, from, len);
+
return ret;
}
@@ -1750,7 +1794,7 @@ static int spi_nor_write(struct mtd_info *mtd, loff_t to, size_t len,
dev_dbg(nor->dev, "to 0x%08x, len %zd\n", (u32)to, len);
- ret = spi_nor_lock_and_prep(nor);
+ ret = spi_nor_lock_and_prep_pe(nor, to, len);
if (ret)
return ret;
@@ -1792,7 +1836,8 @@ static int spi_nor_write(struct mtd_info *mtd, loff_t to, size_t len,
}
write_err:
- spi_nor_unlock_and_unprep(nor);
+ spi_nor_unlock_and_unprep_pe(nor, to, len);
+
return ret;
}
--
2.34.1
More information about the linux-mtd
mailing list