[OpenWrt-Devel] [PATCH 1/2] bcm53xx: backport more spi-nor patches

Rafał Miłecki zajec5 at gmail.com
Wed Aug 20 09:44:53 EDT 2014


Signed-off-by: Rafał Miłecki <zajec5 at gmail.com>
---
 target/linux/bcm53xx/config-3.14                   |   1 +
 .../002-mtd-spi-nor-queued-for-3.18.patch          |  39 +++
 ...pport-for-struct-flash_platform_data-into.patch |  52 +++
 ...-add-Kconfig-option-to-disable-4K-sectors.patch |  44 +++
 ...-allow-NULL-as-spi_device_id-in-spi_nor_s.patch |  46 +++
 .../403-mtd-spi-nor-refactor-wait-till-ready.patch | 374 +++++++++++++++++++++
 6 files changed, 556 insertions(+)
 create mode 100644 target/linux/bcm53xx/patches-3.14/002-mtd-spi-nor-queued-for-3.18.patch
 create mode 100644 target/linux/bcm53xx/patches-3.14/400-mtd-move-support-for-struct-flash_platform_data-into.patch
 create mode 100644 target/linux/bcm53xx/patches-3.14/401-mtd-spi-nor-add-Kconfig-option-to-disable-4K-sectors.patch
 create mode 100644 target/linux/bcm53xx/patches-3.14/402-mtd-spi-nor-allow-NULL-as-spi_device_id-in-spi_nor_s.patch
 create mode 100644 target/linux/bcm53xx/patches-3.14/403-mtd-spi-nor-refactor-wait-till-ready.patch

diff --git a/target/linux/bcm53xx/config-3.14 b/target/linux/bcm53xx/config-3.14
index f703522..e0fd0fd 100644
--- a/target/linux/bcm53xx/config-3.14
+++ b/target/linux/bcm53xx/config-3.14
@@ -168,6 +168,7 @@ CONFIG_MODULES_USE_ELF_REL=y
 CONFIG_MTD_BCM47XX_PARTS=y
 # CONFIG_MTD_PHYSMAP_OF is not set
 CONFIG_MTD_SPI_NOR=y
+# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set
 CONFIG_MULTI_IRQ_HANDLER=y
 CONFIG_MUTEX_SPIN_ON_OWNER=y
 CONFIG_NEED_DMA_MAP_STATE=y
diff --git a/target/linux/bcm53xx/patches-3.14/002-mtd-spi-nor-queued-for-3.18.patch b/target/linux/bcm53xx/patches-3.14/002-mtd-spi-nor-queued-for-3.18.patch
new file mode 100644
index 0000000..7505a17
--- /dev/null
+++ b/target/linux/bcm53xx/patches-3.14/002-mtd-spi-nor-queued-for-3.18.patch
@@ -0,0 +1,39 @@
+--- a/drivers/mtd/spi-nor/spi-nor.c
++++ b/drivers/mtd/spi-nor/spi-nor.c
+@@ -611,6 +611,7 @@ const struct spi_device_id spi_nor_ids[]
+ 	{ "m25px32-s0", INFO(0x207316,  0, 64 * 1024, 64, SECT_4K) },
+ 	{ "m25px32-s1", INFO(0x206316,  0, 64 * 1024, 64, SECT_4K) },
+ 	{ "m25px64",    INFO(0x207117,  0, 64 * 1024, 128, 0) },
++	{ "m25px80",    INFO(0x207114,  0, 64 * 1024, 16, 0) },
+ 
+ 	/* Winbond -- w25x "blocks" are 64K, "sectors" are 4KiB */
+ 	{ "w25x10", INFO(0xef3011, 0, 64 * 1024,  2,  SECT_4K) },
+@@ -623,7 +624,6 @@ const struct spi_device_id spi_nor_ids[]
+ 	{ "w25q32dw", INFO(0xef6016, 0, 64 * 1024,  64, SECT_4K) },
+ 	{ "w25x64", INFO(0xef3017, 0, 64 * 1024, 128, SECT_4K) },
+ 	{ "w25q64", INFO(0xef4017, 0, 64 * 1024, 128, SECT_4K) },
+-	{ "w25q128", INFO(0xef4018, 0, 64 * 1024, 256, SECT_4K) },
+ 	{ "w25q80", INFO(0xef5014, 0, 64 * 1024,  16, SECT_4K) },
+ 	{ "w25q80bl", INFO(0xef4014, 0, 64 * 1024,  16, SECT_4K) },
+ 	{ "w25q128", INFO(0xef4018, 0, 64 * 1024, 256, SECT_4K) },
+@@ -671,11 +671,6 @@ static const struct spi_device_id *spi_n
+ 	return ERR_PTR(-ENODEV);
+ }
+ 
+-static const struct spi_device_id *jedec_probe(struct spi_nor *nor)
+-{
+-	return nor->read_id(nor);
+-}
+-
+ static int spi_nor_read(struct mtd_info *mtd, loff_t from, size_t len,
+ 			size_t *retlen, u_char *buf)
+ {
+@@ -958,7 +953,7 @@ int spi_nor_scan(struct spi_nor *nor, co
+ 	if (info->jedec_id) {
+ 		const struct spi_device_id *jid;
+ 
+-		jid = jedec_probe(nor);
++		jid = nor->read_id(nor);
+ 		if (IS_ERR(jid)) {
+ 			return PTR_ERR(jid);
+ 		} else if (jid != id) {
diff --git a/target/linux/bcm53xx/patches-3.14/400-mtd-move-support-for-struct-flash_platform_data-into.patch b/target/linux/bcm53xx/patches-3.14/400-mtd-move-support-for-struct-flash_platform_data-into.patch
new file mode 100644
index 0000000..8076f55
--- /dev/null
+++ b/target/linux/bcm53xx/patches-3.14/400-mtd-move-support-for-struct-flash_platform_data-into.patch
@@ -0,0 +1,52 @@
+--- a/drivers/mtd/spi-nor/spi-nor.c
++++ b/drivers/mtd/spi-nor/spi-nor.c
+@@ -915,7 +915,6 @@ int spi_nor_scan(struct spi_nor *nor, co
+ 			enum read_mode mode)
+ {
+ 	struct flash_info		*info;
+-	struct flash_platform_data	*data;
+ 	struct device *dev = nor->dev;
+ 	struct mtd_info *mtd = nor->mtd;
+ 	struct device_node *np = dev->of_node;
+@@ -926,28 +925,6 @@ int spi_nor_scan(struct spi_nor *nor, co
+ 	if (ret)
+ 		return ret;
+ 
+-	/* Platform data helps sort out which chip type we have, as
+-	 * well as how this board partitions it.  If we don't have
+-	 * a chip ID, try the JEDEC id commands; they'll work for most
+-	 * newer chips, even if we don't recognize the particular chip.
+-	 */
+-	data = dev_get_platdata(dev);
+-	if (data && data->type) {
+-		const struct spi_device_id *plat_id;
+-
+-		for (i = 0; i < ARRAY_SIZE(spi_nor_ids) - 1; i++) {
+-			plat_id = &spi_nor_ids[i];
+-			if (strcmp(data->type, plat_id->name))
+-				continue;
+-			break;
+-		}
+-
+-		if (i < ARRAY_SIZE(spi_nor_ids) - 1)
+-			id = plat_id;
+-		else
+-			dev_warn(dev, "unrecognized id %s\n", data->type);
+-	}
+-
+ 	info = (void *)id->driver_data;
+ 
+ 	if (info->jedec_id) {
+@@ -985,11 +962,8 @@ int spi_nor_scan(struct spi_nor *nor, co
+ 		write_sr(nor, 0);
+ 	}
+ 
+-	if (data && data->name)
+-		mtd->name = data->name;
+-	else
++	if (!mtd->name)
+ 		mtd->name = dev_name(dev);
+-
+ 	mtd->type = MTD_NORFLASH;
+ 	mtd->writesize = 1;
+ 	mtd->flags = MTD_CAP_NORFLASH;
diff --git a/target/linux/bcm53xx/patches-3.14/401-mtd-spi-nor-add-Kconfig-option-to-disable-4K-sectors.patch b/target/linux/bcm53xx/patches-3.14/401-mtd-spi-nor-add-Kconfig-option-to-disable-4K-sectors.patch
new file mode 100644
index 0000000..395b0af
--- /dev/null
+++ b/target/linux/bcm53xx/patches-3.14/401-mtd-spi-nor-add-Kconfig-option-to-disable-4K-sectors.patch
@@ -0,0 +1,44 @@
+--- a/drivers/mtd/spi-nor/Kconfig
++++ b/drivers/mtd/spi-nor/Kconfig
+@@ -7,6 +7,20 @@ menuconfig MTD_SPI_NOR
+ 
+ if MTD_SPI_NOR
+ 
++config MTD_SPI_NOR_USE_4K_SECTORS
++	bool "Use small 4096 B erase sectors"
++	default y
++	help
++	  Many flash memories support erasing small (4096 B) sectors. Depending
++	  on the usage this feature may provide performance gain in comparison
++	  to erasing whole blocks (32/64 KiB).
++	  Changing small part of flash content is usually faster with small
++	  sectors. On the other hand erasing should be faster when using 64 KiB
++	  block instead of 16 × 4 KiB sectors.
++
++	  Please note that some tools/drivers/filesystems may not work with
++	  4096 B erase size (e.g. UBIFS requires 15 KiB as a minimum).
++
+ config SPI_FSL_QUADSPI
+ 	tristate "Freescale Quad SPI controller"
+ 	depends on ARCH_MXC
+--- a/drivers/mtd/spi-nor/spi-nor.c
++++ b/drivers/mtd/spi-nor/spi-nor.c
+@@ -987,6 +987,7 @@ int spi_nor_scan(struct spi_nor *nor, co
+ 	    nor->wait_till_ready == spi_nor_wait_till_ready)
+ 		nor->wait_till_ready = spi_nor_wait_till_fsr_ready;
+ 
++#ifdef CONFIG_MTD_SPI_NOR_USE_4K_SECTORS
+ 	/* prefer "small sector" erase if possible */
+ 	if (info->flags & SECT_4K) {
+ 		nor->erase_opcode = SPINOR_OP_BE_4K;
+@@ -994,7 +995,9 @@ int spi_nor_scan(struct spi_nor *nor, co
+ 	} else if (info->flags & SECT_4K_PMC) {
+ 		nor->erase_opcode = SPINOR_OP_BE_4K_PMC;
+ 		mtd->erasesize = 4096;
+-	} else {
++	} else
++#endif
++	{
+ 		nor->erase_opcode = SPINOR_OP_SE;
+ 		mtd->erasesize = info->sector_size;
+ 	}
diff --git a/target/linux/bcm53xx/patches-3.14/402-mtd-spi-nor-allow-NULL-as-spi_device_id-in-spi_nor_s.patch b/target/linux/bcm53xx/patches-3.14/402-mtd-spi-nor-allow-NULL-as-spi_device_id-in-spi_nor_s.patch
new file mode 100644
index 0000000..6cc7752
--- /dev/null
+++ b/target/linux/bcm53xx/patches-3.14/402-mtd-spi-nor-allow-NULL-as-spi_device_id-in-spi_nor_s.patch
@@ -0,0 +1,46 @@
+--- a/drivers/mtd/spi-nor/spi-nor.c
++++ b/drivers/mtd/spi-nor/spi-nor.c
+@@ -925,29 +925,23 @@ int spi_nor_scan(struct spi_nor *nor, co
+ 	if (ret)
+ 		return ret;
+ 
+-	info = (void *)id->driver_data;
+-
+-	if (info->jedec_id) {
+-		const struct spi_device_id *jid;
+-
+-		jid = nor->read_id(nor);
+-		if (IS_ERR(jid)) {
+-			return PTR_ERR(jid);
+-		} else if (jid != id) {
+-			/*
+-			 * JEDEC knows better, so overwrite platform ID. We
+-			 * can't trust partitions any longer, but we'll let
+-			 * mtd apply them anyway, since some partitions may be
+-			 * marked read-only, and we don't want to lose that
+-			 * information, even if it's not 100% accurate.
+-			 */
+-			dev_warn(dev, "found %s, expected %s\n",
+-				 jid->name, id->name);
+-			id = jid;
+-			info = (void *)jid->driver_data;
++	if (id) {
++		info = (void *)id->driver_data;
++		if (info->jedec_id) {
++			dev_warn(dev,
++				 "passed SPI device ID (%s) contains JEDEC, ignoring it, driver should be fixed!\n",
++				 id->name);
++			id = NULL;
+ 		}
+ 	}
+ 
++	if (!id) {
++		id = nor->read_id(nor);
++		if (IS_ERR(id))
++			return PTR_ERR(id);
++	}
++	info = (void *)id->driver_data;
++
+ 	mutex_init(&nor->lock);
+ 
+ 	/*
diff --git a/target/linux/bcm53xx/patches-3.14/403-mtd-spi-nor-refactor-wait-till-ready.patch b/target/linux/bcm53xx/patches-3.14/403-mtd-spi-nor-refactor-wait-till-ready.patch
new file mode 100644
index 0000000..79a5131
--- /dev/null
+++ b/target/linux/bcm53xx/patches-3.14/403-mtd-spi-nor-refactor-wait-till-ready.patch
@@ -0,0 +1,374 @@
+--- a/drivers/mtd/spi-nor/fsl-quadspi.c
++++ b/drivers/mtd/spi-nor/fsl-quadspi.c
+@@ -719,16 +719,10 @@ static int fsl_qspi_read(struct spi_nor
+ {
+ 	struct fsl_qspi *q = nor->priv;
+ 	u8 cmd = nor->read_opcode;
+-	int ret;
+ 
+ 	dev_dbg(q->dev, "cmd [%x],read from (0x%p, 0x%.8x, 0x%.8x),len:%d\n",
+ 		cmd, q->ahb_base, q->chip_base_addr, (unsigned int)from, len);
+ 
+-	/* Wait until the previous command is finished. */
+-	ret = nor->wait_till_ready(nor);
+-	if (ret)
+-		return ret;
+-
+ 	/* Read out the data directly from the AHB buffer.*/
+ 	memcpy(buf, q->ahb_base + q->chip_base_addr + from, len);
+ 
+@@ -744,16 +738,6 @@ static int fsl_qspi_erase(struct spi_nor
+ 	dev_dbg(nor->dev, "%dKiB at 0x%08x:0x%08x\n",
+ 		nor->mtd->erasesize / 1024, q->chip_base_addr, (u32)offs);
+ 
+-	/* Wait until finished previous write command. */
+-	ret = nor->wait_till_ready(nor);
+-	if (ret)
+-		return ret;
+-
+-	/* Send write enable, then erase commands. */
+-	ret = nor->write_reg(nor, SPINOR_OP_WREN, NULL, 0, 0);
+-	if (ret)
+-		return ret;
+-
+ 	ret = fsl_qspi_runcmd(q, nor->erase_opcode, offs, 0);
+ 	if (ret)
+ 		return ret;
+--- a/drivers/mtd/spi-nor/spi-nor.c
++++ b/drivers/mtd/spi-nor/spi-nor.c
+@@ -163,81 +163,69 @@ static inline int set_4byte(struct spi_n
+ 		return nor->write_reg(nor, SPINOR_OP_BRWR, nor->cmd_buf, 1, 0);
+ 	}
+ }
+-
+-static int spi_nor_wait_till_ready(struct spi_nor *nor)
++static inline int spi_nor_sr_ready(struct spi_nor *nor)
+ {
+-	unsigned long deadline;
+-	int sr;
+-
+-	deadline = jiffies + MAX_READY_WAIT_JIFFIES;
+-
+-	do {
+-		cond_resched();
++	int sr = read_sr(nor);
++	if (sr < 0)
++		return sr;
++	else
++		return !(sr & SR_WIP);
++}
+ 
+-		sr = read_sr(nor);
+-		if (sr < 0)
+-			break;
+-		else if (!(sr & SR_WIP))
+-			return 0;
+-	} while (!time_after_eq(jiffies, deadline));
++static inline int spi_nor_fsr_ready(struct spi_nor *nor)
++{
++	int fsr = read_fsr(nor);
++	if (fsr < 0)
++		return fsr;
++	else
++		return fsr & FSR_READY;
++}
+ 
+-	return -ETIMEDOUT;
++static int spi_nor_ready(struct spi_nor *nor)
++{
++	int sr, fsr;
++	sr = spi_nor_sr_ready(nor);
++	if (sr < 0)
++		return sr;
++	fsr = nor->flags & SNOR_F_USE_FSR ? spi_nor_fsr_ready(nor) : 1;
++	if (fsr < 0)
++		return sr;
++	return sr && fsr;
+ }
+ 
+-static int spi_nor_wait_till_fsr_ready(struct spi_nor *nor)
++/*
++ * Service routine to read status register until ready, or timeout occurs.
++ * Returns non-zero if error.
++ */
++static int spi_nor_wait_till_ready(struct spi_nor *nor)
+ {
+ 	unsigned long deadline;
+-	int sr;
+-	int fsr;
++	int ret;
+ 
+ 	deadline = jiffies + MAX_READY_WAIT_JIFFIES;
+ 
+ 	do {
+ 		cond_resched();
+ 
+-		sr = read_sr(nor);
+-		if (sr < 0) {
+-			break;
+-		} else if (!(sr & SR_WIP)) {
+-			fsr = read_fsr(nor);
+-			if (fsr < 0)
+-				break;
+-			if (fsr & FSR_READY)
+-				return 0;
+-		}
++		ret = spi_nor_ready(nor);
++		if (ret < 0)
++			return ret;
++		if (ret)
++			return 0;
+ 	} while (!time_after_eq(jiffies, deadline));
+ 
+ 	return -ETIMEDOUT;
+ }
+ 
+ /*
+- * Service routine to read status register until ready, or timeout occurs.
+- * Returns non-zero if error.
+- */
+-static int wait_till_ready(struct spi_nor *nor)
+-{
+-	return nor->wait_till_ready(nor);
+-}
+-
+-/*
+  * Erase the whole flash memory
+  *
+  * Returns 0 if successful, non-zero otherwise.
+  */
+ static int erase_chip(struct spi_nor *nor)
+ {
+-	int ret;
+-
+ 	dev_dbg(nor->dev, " %lldKiB\n", (long long)(nor->mtd->size >> 10));
+ 
+-	/* Wait until finished previous write command. */
+-	ret = wait_till_ready(nor);
+-	if (ret)
+-		return ret;
+-
+-	/* Send write enable, then erase commands. */
+-	write_enable(nor);
+-
+ 	return nor->write_reg(nor, SPINOR_OP_CHIP_ERASE, NULL, 0, 0);
+ }
+ 
+@@ -290,6 +278,8 @@ static int spi_nor_erase(struct mtd_info
+ 	if (ret)
+ 		return ret;
+ 
++	write_enable(nor);
++
+ 	/* whole-chip erase? */
+ 	if (len == mtd->size) {
+ 		if (erase_chip(nor)) {
+@@ -297,6 +287,10 @@ static int spi_nor_erase(struct mtd_info
+ 			goto erase_err;
+ 		}
+ 
++		ret = spi_nor_wait_till_ready(nor);
++		if (ret)
++			goto erase_err;
++
+ 	/* REVISIT in some cases we could speed up erasing large regions
+ 	 * by using SPINOR_OP_SE instead of SPINOR_OP_BE_4K.  We may have set up
+ 	 * to use "small sector erase", but that's not always optimal.
+@@ -312,9 +306,15 @@ static int spi_nor_erase(struct mtd_info
+ 
+ 			addr += mtd->erasesize;
+ 			len -= mtd->erasesize;
++
++			ret = spi_nor_wait_till_ready(nor);
++			if (ret)
++				goto erase_err;
+ 		}
+ 	}
+ 
++	write_disable(nor);
++
+ 	spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_ERASE);
+ 
+ 	instr->state = MTD_ERASE_DONE;
+@@ -339,11 +339,6 @@ static int spi_nor_lock(struct mtd_info
+ 	if (ret)
+ 		return ret;
+ 
+-	/* Wait until finished previous command */
+-	ret = wait_till_ready(nor);
+-	if (ret)
+-		goto err;
+-
+ 	status_old = read_sr(nor);
+ 
+ 	if (offset < mtd->size - (mtd->size / 2))
+@@ -386,11 +381,6 @@ static int spi_nor_unlock(struct mtd_inf
+ 	if (ret)
+ 		return ret;
+ 
+-	/* Wait until finished previous command */
+-	ret = wait_till_ready(nor);
+-	if (ret)
+-		goto err;
+-
+ 	status_old = read_sr(nor);
+ 
+ 	if (offset+len > mtd->size - (mtd->size / 64))
+@@ -702,11 +692,6 @@ static int sst_write(struct mtd_info *mt
+ 	if (ret)
+ 		return ret;
+ 
+-	/* Wait until finished previous write command. */
+-	ret = wait_till_ready(nor);
+-	if (ret)
+-		goto time_out;
+-
+ 	write_enable(nor);
+ 
+ 	nor->sst_write_second = false;
+@@ -718,7 +703,7 @@ static int sst_write(struct mtd_info *mt
+ 
+ 		/* write one byte. */
+ 		nor->write(nor, to, 1, retlen, buf);
+-		ret = wait_till_ready(nor);
++		ret = spi_nor_wait_till_ready(nor);
+ 		if (ret)
+ 			goto time_out;
+ 	}
+@@ -730,7 +715,7 @@ static int sst_write(struct mtd_info *mt
+ 
+ 		/* write two bytes. */
+ 		nor->write(nor, to, 2, retlen, buf + actual);
+-		ret = wait_till_ready(nor);
++		ret = spi_nor_wait_till_ready(nor);
+ 		if (ret)
+ 			goto time_out;
+ 		to += 2;
+@@ -739,7 +724,7 @@ static int sst_write(struct mtd_info *mt
+ 	nor->sst_write_second = false;
+ 
+ 	write_disable(nor);
+-	ret = wait_till_ready(nor);
++	ret = spi_nor_wait_till_ready(nor);
+ 	if (ret)
+ 		goto time_out;
+ 
+@@ -750,7 +735,7 @@ static int sst_write(struct mtd_info *mt
+ 		nor->program_opcode = SPINOR_OP_BP;
+ 		nor->write(nor, to, 1, retlen, buf + actual);
+ 
+-		ret = wait_till_ready(nor);
++		ret = spi_nor_wait_till_ready(nor);
+ 		if (ret)
+ 			goto time_out;
+ 		write_disable(nor);
+@@ -778,11 +763,6 @@ static int spi_nor_write(struct mtd_info
+ 	if (ret)
+ 		return ret;
+ 
+-	/* Wait until finished previous write command. */
+-	ret = wait_till_ready(nor);
+-	if (ret)
+-		goto write_err;
+-
+ 	write_enable(nor);
+ 
+ 	page_offset = to & (nor->page_size - 1);
+@@ -801,16 +781,20 @@ static int spi_nor_write(struct mtd_info
+ 			if (page_size > nor->page_size)
+ 				page_size = nor->page_size;
+ 
+-			wait_till_ready(nor);
++			ret = spi_nor_wait_till_ready(nor);
++			if (ret)
++				goto write_err;
++
+ 			write_enable(nor);
+ 
+ 			nor->write(nor, to + i, page_size, retlen, buf + i);
+ 		}
+ 	}
+ 
++	ret = spi_nor_wait_till_ready(nor);
+ write_err:
+ 	spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_WRITE);
+-	return 0;
++	return ret;
+ }
+ 
+ static int macronix_quad_enable(struct spi_nor *nor)
+@@ -823,7 +807,7 @@ static int macronix_quad_enable(struct s
+ 	nor->cmd_buf[0] = val | SR_QUAD_EN_MX;
+ 	nor->write_reg(nor, SPINOR_OP_WRSR, nor->cmd_buf, 1, 0);
+ 
+-	if (wait_till_ready(nor))
++	if (spi_nor_wait_till_ready(nor))
+ 		return 1;
+ 
+ 	ret = read_sr(nor);
+@@ -905,8 +889,6 @@ static int spi_nor_check(struct spi_nor
+ 
+ 	if (!nor->read_id)
+ 		nor->read_id = spi_nor_read_id;
+-	if (!nor->wait_till_ready)
+-		nor->wait_till_ready = spi_nor_wait_till_ready;
+ 
+ 	return 0;
+ }
+@@ -977,9 +959,8 @@ int spi_nor_scan(struct spi_nor *nor, co
+ 	else
+ 		mtd->_write = spi_nor_write;
+ 
+-	if ((info->flags & USE_FSR) &&
+-	    nor->wait_till_ready == spi_nor_wait_till_ready)
+-		nor->wait_till_ready = spi_nor_wait_till_fsr_ready;
++	if (info->flags & USE_FSR)
++		nor->flags |= SNOR_F_USE_FSR;
+ 
+ #ifdef CONFIG_MTD_SPI_NOR_USE_4K_SECTORS
+ 	/* prefer "small sector" erase if possible */
+--- a/include/linux/mtd/spi-nor.h
++++ b/include/linux/mtd/spi-nor.h
+@@ -116,6 +116,10 @@ enum spi_nor_ops {
+ 	SPI_NOR_OPS_UNLOCK,
+ };
+ 
++enum spi_nor_option_flags {
++	SNOR_F_USE_FSR		= BIT(0),
++};
++
+ /**
+  * struct spi_nor - Structure for defining a the SPI NOR layer
+  * @mtd:		point to a mtd_info structure
+@@ -129,6 +133,7 @@ enum spi_nor_ops {
+  * @program_opcode:	the program opcode
+  * @flash_read:		the mode of the read
+  * @sst_write_second:	used by the SST write operation
++ * @flags:		flag options for the current SPI-NOR (SNOR_F_*)
+  * @cfg:		used by the read_xfer/write_xfer
+  * @cmd_buf:		used by the write_reg
+  * @prepare:		[OPTIONAL] do some preparations for the
+@@ -141,7 +146,6 @@ enum spi_nor_ops {
+  * @write_reg:		[DRIVER-SPECIFIC] write data to the register
+  * @read_id:		[REPLACEABLE] read out the ID data, and find
+  *			the proper spi_device_id
+- * @wait_till_ready:	[REPLACEABLE] wait till the NOR becomes ready
+  * @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
+@@ -160,6 +164,7 @@ struct spi_nor {
+ 	u8			program_opcode;
+ 	enum read_mode		flash_read;
+ 	bool			sst_write_second;
++	u32			flags;
+ 	struct spi_nor_xfer_cfg	cfg;
+ 	u8			cmd_buf[SPI_NOR_MAX_CMD_SIZE];
+ 
+@@ -173,7 +178,6 @@ struct spi_nor {
+ 	int (*write_reg)(struct spi_nor *nor, u8 opcode, u8 *buf, int len,
+ 			int write_enable);
+ 	const struct spi_device_id *(*read_id)(struct spi_nor *nor);
+-	int (*wait_till_ready)(struct spi_nor *nor);
+ 
+ 	int (*read)(struct spi_nor *nor, loff_t from,
+ 			size_t len, size_t *retlen, u_char *read_buf);
-- 
1.8.4.5
_______________________________________________
openwrt-devel mailing list
openwrt-devel at lists.openwrt.org
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel


More information about the openwrt-devel mailing list