All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 1/2] mtd: spi-nor: provide default erase_sector implementation
@ 2015-11-10 20:15 Brian Norris
  2015-11-10 20:15 ` [PATCH v2 2/2] mtd: m25p80: drop erase() callback Brian Norris
  2015-11-19 21:35 ` [PATCH v2 1/2] mtd: spi-nor: provide default erase_sector implementation Brian Norris
  0 siblings, 2 replies; 3+ messages in thread
From: Brian Norris @ 2015-11-10 20:15 UTC (permalink / raw)
  To: linux-mtd; +Cc: Brian Norris, Bayi Cheng, Marek Vasut

Some spi-nor drivers perform sector erase by duplicating their
write_reg() command. Let's not require that the driver fill this out,
and provide a default instead.

Tested on m25p80.c and Medatek's MT8173 SPI NOR flash driver.

Signed-off-by: Brian Norris <computersforpeace@gmail.com>
---
v1 -> v2:
  * use statically-sized array, with a check to make sure MAX is big enough

v1: http://lists.infradead.org/pipermail/linux-mtd/2015-October/062916.html

 drivers/mtd/spi-nor/spi-nor.c | 37 +++++++++++++++++++++++++++++++++----
 include/linux/mtd/spi-nor.h   |  3 ++-
 2 files changed, 35 insertions(+), 5 deletions(-)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index 49883905a434..aa85564cf25a 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -38,6 +38,7 @@
 #define CHIP_ERASE_2MB_READY_WAIT_JIFFIES	(40UL * HZ)
 
 #define SPI_NOR_MAX_ID_LEN	6
+#define SPI_NOR_MAX_ADDR_WIDTH	4
 
 struct flash_info {
 	char		*name;
@@ -313,6 +314,29 @@ static void spi_nor_unlock_and_unprep(struct spi_nor *nor, enum spi_nor_ops ops)
 }
 
 /*
+ * Initiate the erasure of a single sector
+ */
+static int spi_nor_erase_sector(struct spi_nor *nor, u32 addr)
+{
+	u8 buf[SPI_NOR_MAX_ADDR_WIDTH];
+	int i;
+
+	if (nor->erase)
+		return nor->erase(nor, addr);
+
+	/*
+	 * Default implementation, if driver doesn't have a specialized HW
+	 * control
+	 */
+	for (i = nor->addr_width - 1; i >= 0; i--) {
+		buf[i] = addr & 0xff;
+		addr >>= 8;
+	}
+
+	return nor->write_reg(nor, nor->erase_opcode, buf, nor->addr_width);
+}
+
+/*
  * Erase an address range on the nor chip.  The address range may extend
  * one or more erase sectors.  Return an error is there is a problem erasing.
  */
@@ -371,10 +395,9 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr)
 		while (len) {
 			write_enable(nor);
 
-			if (nor->erase(nor, addr)) {
-				ret = -EIO;
+			ret = spi_nor_erase_sector(nor, addr);
+			if (ret)
 				goto erase_err;
-			}
 
 			addr += mtd->erasesize;
 			len -= mtd->erasesize;
@@ -1138,7 +1161,7 @@ static int set_quad_mode(struct spi_nor *nor, const struct flash_info *info)
 static int spi_nor_check(struct spi_nor *nor)
 {
 	if (!nor->dev || !nor->read || !nor->write ||
-		!nor->read_reg || !nor->write_reg || !nor->erase) {
+		!nor->read_reg || !nor->write_reg) {
 		pr_err("spi-nor: please fill all the necessary fields!\n");
 		return -EINVAL;
 	}
@@ -1340,6 +1363,12 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode)
 		nor->addr_width = 3;
 	}
 
+	if (nor->addr_width > SPI_NOR_MAX_ADDR_WIDTH) {
+		dev_err(dev, "address width is too large: %u\n",
+			nor->addr_width);
+		return -EINVAL;
+	}
+
 	nor->read_dummy = spi_nor_read_dummy_cycles(nor);
 
 	dev_info(dev, "%s (%lld Kbytes)\n", info->name,
diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
index c8723b62c4cd..69898b675ade 100644
--- a/include/linux/mtd/spi-nor.h
+++ b/include/linux/mtd/spi-nor.h
@@ -144,7 +144,8 @@ struct mtd_info;
  * @read:		[DRIVER-SPECIFIC] read data from the SPI NOR
  * @write:		[DRIVER-SPECIFIC] write data to the SPI NOR
  * @erase:		[DRIVER-SPECIFIC] erase a sector of the SPI NOR
- *			at the offset @offs
+ *			at the offset @offs; if not provided by the driver,
+ *			spi-nor will send the erase opcode via write_reg()
  * @flash_lock:		[FLASH-SPECIFIC] lock a region of the SPI NOR
  * @flash_unlock:	[FLASH-SPECIFIC] unlock a region of the SPI NOR
  * @flash_is_locked:	[FLASH-SPECIFIC] check if a region of the SPI NOR is
-- 
2.6.0.rc2.230.g3dd15c0

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH v2 2/2] mtd: m25p80: drop erase() callback
  2015-11-10 20:15 [PATCH v2 1/2] mtd: spi-nor: provide default erase_sector implementation Brian Norris
@ 2015-11-10 20:15 ` Brian Norris
  2015-11-19 21:35 ` [PATCH v2 1/2] mtd: spi-nor: provide default erase_sector implementation Brian Norris
  1 sibling, 0 replies; 3+ messages in thread
From: Brian Norris @ 2015-11-10 20:15 UTC (permalink / raw)
  To: linux-mtd; +Cc: Brian Norris, Bayi Cheng, Marek Vasut

Just use the spi-nor default instead.

Signed-off-by: Brian Norris <computersforpeace@gmail.com>
---
v2: no change

v1: http://lists.infradead.org/pipermail/linux-mtd/2015-October/062917.html

 drivers/mtd/devices/m25p80.c | 17 -----------------
 1 file changed, 17 deletions(-)

diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index 4b5d7a4655fd..822b6c73dd50 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -152,22 +152,6 @@ static int m25p80_read(struct spi_nor *nor, loff_t from, size_t len,
 	return 0;
 }
 
-static int m25p80_erase(struct spi_nor *nor, loff_t offset)
-{
-	struct m25p *flash = nor->priv;
-
-	dev_dbg(nor->dev, "%dKiB at 0x%08x\n",
-		flash->spi_nor.mtd.erasesize / 1024, (u32)offset);
-
-	/* Set up command buffer. */
-	flash->command[0] = nor->erase_opcode;
-	m25p_addr2cmd(nor, offset, flash->command);
-
-	spi_write(flash->spi, flash->command, m25p_cmdsz(nor));
-
-	return 0;
-}
-
 /*
  * board specific setup should have ensured the SPI clock used here
  * matches what the READ command supports, at least until this driver
@@ -194,7 +178,6 @@ static int m25p_probe(struct spi_device *spi)
 	/* install the hooks */
 	nor->read = m25p80_read;
 	nor->write = m25p80_write;
-	nor->erase = m25p80_erase;
 	nor->write_reg = m25p80_write_reg;
 	nor->read_reg = m25p80_read_reg;
 
-- 
2.6.0.rc2.230.g3dd15c0

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH v2 1/2] mtd: spi-nor: provide default erase_sector implementation
  2015-11-10 20:15 [PATCH v2 1/2] mtd: spi-nor: provide default erase_sector implementation Brian Norris
  2015-11-10 20:15 ` [PATCH v2 2/2] mtd: m25p80: drop erase() callback Brian Norris
@ 2015-11-19 21:35 ` Brian Norris
  1 sibling, 0 replies; 3+ messages in thread
From: Brian Norris @ 2015-11-19 21:35 UTC (permalink / raw)
  To: linux-mtd; +Cc: Bayi Cheng, Marek Vasut

On Tue, Nov 10, 2015 at 12:15:27PM -0800, Brian Norris wrote:
> Some spi-nor drivers perform sector erase by duplicating their
> write_reg() command. Let's not require that the driver fill this out,
> and provide a default instead.
> 
> Tested on m25p80.c and Medatek's MT8173 SPI NOR flash driver.
> 
> Signed-off-by: Brian Norris <computersforpeace@gmail.com>
> ---
> v1 -> v2:
>   * use statically-sized array, with a check to make sure MAX is big enough
> 
> v1: http://lists.infradead.org/pipermail/linux-mtd/2015-October/062916.html

Pushed both to l2-mtd.git

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2015-11-19 21:35 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-11-10 20:15 [PATCH v2 1/2] mtd: spi-nor: provide default erase_sector implementation Brian Norris
2015-11-10 20:15 ` [PATCH v2 2/2] mtd: m25p80: drop erase() callback Brian Norris
2015-11-19 21:35 ` [PATCH v2 1/2] mtd: spi-nor: provide default erase_sector implementation Brian Norris

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.