[PATCH] mtd: m25p80: make it possible to use large blocks if desired

Sascha Hauer s.hauer at pengutronix.de
Wed Aug 26 06:15:02 PDT 2015


Some SPI NOR flashes support 4K erase blocks. 4K erase blocks do not
work with UBIFS which needs a minimum erase block size of 15360 bytes.
Also bigger sectors are faster to erase. This patch adds a device tree
option to use the bigger blocks instead of the default 4K blocks.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
Signed-off-by: Philipp Zabel <p.zabel at pengutronix.de>
---
 Documentation/devicetree/bindings/mtd/m25p80.rst | 10 ++++++++++
 drivers/mtd/devices/m25p80.c                     |  6 +++++-
 drivers/mtd/spi-nor/cadence-quadspi.c            |  2 +-
 drivers/mtd/spi-nor/spi-nor.c                    |  7 ++++---
 include/linux/mtd/spi-nor.h                      |  4 +++-
 5 files changed, 23 insertions(+), 6 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/mtd/m25p80.rst

diff --git a/Documentation/devicetree/bindings/mtd/m25p80.rst b/Documentation/devicetree/bindings/mtd/m25p80.rst
new file mode 100644
index 0000000..d7c8914
--- /dev/null
+++ b/Documentation/devicetree/bindings/mtd/m25p80.rst
@@ -0,0 +1,10 @@
+MTD SPI driver for ST M25Pxx (and similar) serial flash chips
+=============================================================
+
+Additionally to the Linux bindings in ``dts/Bindings/mtd/m25p80.txt``
+the barebox driver has the following optional properties:
+
+- use-large-blocks : Use large blocks rather than the 4K blocks some devices
+                     support. 4K erase blocks do not work with UBIFS which needs
+		     a minimum erase block size of 15360 bytes. Also bigger sectors
+		     are faster to erase.
diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index 794c9db..d627690 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -235,6 +235,7 @@ static int m25p_probe(struct device_d *dev)
 	enum read_mode mode =		SPI_NOR_NORMAL;
 	const char			*flash_name = NULL;
 	int				device_id;
+	bool				use_large_blocks;
 	int ret;
 
 	data = dev->platform_data;
@@ -272,7 +273,10 @@ static int m25p_probe(struct device_d *dev)
 	else
 		flash_name = NULL; /* auto-detect */
 
-	ret = spi_nor_scan(nor, flash_name, mode);
+	use_large_blocks = of_property_read_bool(dev->device_node,
+			"use-large-blocks");
+
+	ret = spi_nor_scan(nor, flash_name, mode, use_large_blocks);
 	if (ret)
 		return ret;
 
diff --git a/drivers/mtd/spi-nor/cadence-quadspi.c b/drivers/mtd/spi-nor/cadence-quadspi.c
index dce29ca..ff7bb7a 100644
--- a/drivers/mtd/spi-nor/cadence-quadspi.c
+++ b/drivers/mtd/spi-nor/cadence-quadspi.c
@@ -1078,7 +1078,7 @@ static int cqspi_setup_flash(struct device_d *dev,
 	nor->write = cqspi_write;
 	nor->erase = cqspi_erase;
 
-	ret = spi_nor_scan(nor, NULL, SPI_NOR_QUAD);
+	ret = spi_nor_scan(nor, NULL, SPI_NOR_QUAD, false);
 	if (ret)
 		goto probe_failed;
 
diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index c85ed34..edf0dd5 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -923,7 +923,8 @@ static int spi_nor_check(struct spi_nor *nor)
 	return 0;
 }
 
-int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode)
+int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode,
+		 bool use_large_blocks)
 {
 	const struct spi_device_id	*id = NULL;
 	struct flash_info		*info;
@@ -1012,10 +1013,10 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode)
 
 #ifdef CONFIG_MTD_SPI_NOR_USE_4K_SECTORS
 	/* prefer "small sector" erase if possible */
-	if (info->flags & SECT_4K) {
+	if (info->flags & SECT_4K && !use_large_blocks) {
 		nor->erase_opcode = SPINOR_OP_BE_4K;
 		mtd->erasesize = 4096;
-	} else if (info->flags & SECT_4K_PMC) {
+	} else if (info->flags & SECT_4K_PMC && !use_large_blocks) {
 		nor->erase_opcode = SPINOR_OP_BE_4K_PMC;
 		mtd->erasesize = 4096;
 	} else
diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
index f099406..bd2b16d 100644
--- a/include/linux/mtd/spi-nor.h
+++ b/include/linux/mtd/spi-nor.h
@@ -190,6 +190,7 @@ struct spi_nor {
  * @nor:	the spi_nor structure
  * @name:	the chip type name
  * @mode:	the read mode supported by the driver
+ * @use_large_blocks: prefer large blocks even if 4k blocks are supported
  *
  * The drivers can use this fuction to scan the SPI NOR.
  * In the scanning, it will try to get all the necessary information to
@@ -199,6 +200,7 @@ struct spi_nor {
  *
  * Return: 0 for success, others for failure.
  */
-int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode);
+int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode,
+		 bool use_large_blocks);
 
 #endif
-- 
2.5.0




More information about the barebox mailing list