[PATCH 1/2] mtd: spi-nor: core: Add a helper to read with alternative method
tkuw584924 at gmail.com
tkuw584924 at gmail.com
Fri Aug 12 01:06:32 PDT 2022
From: Takahiro Kuwano <Takahiro.Kuwano at infineon.com>
The existing spi_nor_read_data() uses preset opcode, number of address
bytes, and dummy cycles. During SFDP parse and corresponding fixups we
need to perform read op with different opcode, number of address, and/or
dummy cycles from preset ones. The spi_nor_alt_read() helps that by
backup - read op - restore the preset opcode, etc.
Signed-off-by: Takahiro Kuwano <Takahiro.Kuwano at infineon.com>
---
drivers/mtd/spi-nor/core.c | 48 ++++++++++++++++++++++++++++++++++++++
drivers/mtd/spi-nor/core.h | 2 ++
2 files changed, 50 insertions(+)
diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index f2c64006f8d7..ae98b4ad9b19 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -247,6 +247,54 @@ ssize_t spi_nor_read_data(struct spi_nor *nor, loff_t from, size_t len, u8 *buf)
return nor->controller_ops->read(nor, from, len, buf);
}
+/**
+ * spi_nor_alt_read() - read data from flash memory with alternative opcode,
+ * number of address bytes, and dummy cycles.
+ * @nor: pointer to 'struct spi_nor'
+ * @from: offset to read from
+ * @len: number of bytes to read
+ * @buf: pointer to dst buffer
+ * @read_opcode: read opcode to issue
+ * @addr_nbytes: number of address bytes to send
+ * @read_dummy: number of dummy cycles needed to read
+ *
+ * Return: 0 on success, -errno otherwise
+ */
+int spi_nor_alt_read(struct spi_nor *nor, u32 addr, size_t len, u8 *buf,
+ u8 read_opcode, u8 addr_nbytes, u8 read_dummy)
+{
+ u8 bak_read_opcode = nor->read_opcode;
+ u8 bak_addr_nbytes = nor->addr_nbytes;
+ u8 bak_read_dummy = nor->read_dummy;
+ ssize_t ret;
+
+ nor->read_opcode = read_opcode;
+ nor->addr_nbytes = addr_nbytes;
+ nor->read_dummy = read_dummy;
+
+ while (len) {
+ ret = spi_nor_read_data(nor, addr, len, buf);
+ if (ret < 0)
+ goto out;
+ if (!ret || ret > len) {
+ ret = -EIO;
+ goto out;
+ }
+
+ buf += ret;
+ addr += ret;
+ len -= ret;
+ }
+ ret = 0;
+
+out:
+ nor->read_opcode = bak_read_opcode;
+ nor->addr_nbytes = bak_addr_nbytes;
+ nor->read_dummy = bak_read_dummy;
+
+ return ret;
+}
+
/**
* spi_nor_spimem_write_data() - write data to flash memory via
* spi-mem
diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h
index 85b0cf254e97..4f1e636f9362 100644
--- a/drivers/mtd/spi-nor/core.h
+++ b/drivers/mtd/spi-nor/core.h
@@ -656,6 +656,8 @@ ssize_t spi_nor_read_data(struct spi_nor *nor, loff_t from, size_t len,
u8 *buf);
ssize_t spi_nor_write_data(struct spi_nor *nor, loff_t to, size_t len,
const u8 *buf);
+int spi_nor_alt_read(struct spi_nor *nor, u32 addr, size_t len, u8 *buf,
+ u8 read_opcode, u8 addr_nbytes, u8 read_dummy);
int spi_nor_read_any_reg(struct spi_nor *nor, struct spi_mem_op *op,
enum spi_nor_protocol proto);
int spi_nor_write_any_volatile_reg(struct spi_nor *nor, struct spi_mem_op *op,
--
2.25.1
More information about the linux-mtd
mailing list