From: Rafał Miłecki <zajec5@gmail.com>
Date: Wed, 17 Dec 2014 14:53:25 +0000 (+0000)
Subject: bcm53xx: backport spi-nor changes and update bcm53xxspiflash
X-Git-Url: http://git.cdn.openwrt.org/?a=commitdiff_plain;h=e21e9c55484762a3bc4fe6521d5b1fc84bfa1a1e;p=openwrt%2Fstaging%2Frobimarko.git

bcm53xx: backport spi-nor changes and update bcm53xxspiflash

Signed-off-by: Rafał Miłecki <zajec5@gmail.com>

SVN-Revision: 43738
---

diff --git a/target/linux/bcm53xx/files/drivers/mtd/spi-nor/bcm53xxspiflash.c b/target/linux/bcm53xx/files/drivers/mtd/spi-nor/bcm53xxspiflash.c
new file mode 100644
index 0000000000..f192f4e59b
--- /dev/null
+++ b/target/linux/bcm53xx/files/drivers/mtd/spi-nor/bcm53xxspiflash.c
@@ -0,0 +1,227 @@
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/spi/spi.h>
+#include <linux/mtd/spi-nor.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/cfi.h>
+
+static const char * const probes[] = { "bcm47xxpart", NULL };
+
+struct bcm53xxsf {
+	struct spi_device *spi;
+	struct mtd_info mtd;
+	struct spi_nor nor;
+};
+
+/**************************************************
+ * spi-nor API
+ **************************************************/
+
+static int bcm53xxspiflash_read_reg(struct spi_nor *nor, u8 opcode, u8 *buf,
+				   int len)
+{
+	struct bcm53xxsf *b53sf = nor->priv;
+
+	return spi_write_then_read(b53sf->spi, &opcode, 1, buf, len);
+}
+
+static int bcm53xxspiflash_write_reg(struct spi_nor *nor, u8 opcode, u8 *buf,
+				     int len, int write_enable)
+{
+	struct bcm53xxsf *b53sf = nor->priv;
+	u8 *cmd = kzalloc(len + 1, GFP_KERNEL);
+	int err;
+
+	if (!cmd)
+		return -ENOMEM;
+
+	cmd[0] = opcode;
+	memcpy(&cmd[1], buf, len);
+	err = spi_write(b53sf->spi, cmd, len + 1);
+
+	kfree(cmd);
+
+	return err;
+}
+
+static int bcm53xxspiflash_read(struct spi_nor *nor, loff_t from, size_t len,
+				size_t *retlen, u_char *buf)
+{
+	struct bcm53xxsf *b53sf = nor->priv;
+	struct spi_message m;
+	struct spi_transfer t[2] = { { 0 }, { 0 } };
+	unsigned char cmd[5];
+	int cmd_len = 0;
+	int err;
+
+	spi_message_init(&m);
+
+	cmd[cmd_len++] = SPINOR_OP_READ;
+	if (b53sf->mtd.size > 0x1000000)
+		cmd[cmd_len++] = (from & 0xFF000000) >> 24;
+	cmd[cmd_len++] = (from & 0x00FF0000) >> 16;
+	cmd[cmd_len++] = (from & 0x0000FF00) >> 8;
+	cmd[cmd_len++] = (from & 0x000000FF) >> 0;
+
+	t[0].tx_buf = cmd;
+	t[0].len = cmd_len;
+	spi_message_add_tail(&t[0], &m);
+
+	t[1].rx_buf = buf;
+	t[1].len = len;
+	spi_message_add_tail(&t[1], &m);
+
+	err = spi_sync(b53sf->spi, &m);
+	if (err)
+		return err;
+
+	if (retlen && m.actual_length > cmd_len)
+		*retlen = m.actual_length - cmd_len;
+
+	return 0;
+}
+
+static void bcm53xxspiflash_write(struct spi_nor *nor, loff_t to, size_t len,
+				  size_t *retlen, const u_char *buf)
+{
+	struct bcm53xxsf *b53sf = nor->priv;
+	struct spi_message m;
+	struct spi_transfer t = { 0 };
+	u8 *cmd = kzalloc(len + 5, GFP_KERNEL);
+	int cmd_len = 0;
+	int err;
+
+	if (!cmd)
+		return;
+
+	spi_message_init(&m);
+
+	cmd[cmd_len++] = nor->program_opcode;
+	if (b53sf->mtd.size > 0x1000000)
+		cmd[cmd_len++] = (to & 0xFF000000) >> 24;
+	cmd[cmd_len++] = (to & 0x00FF0000) >> 16;
+	cmd[cmd_len++] = (to & 0x0000FF00) >> 8;
+	cmd[cmd_len++] = (to & 0x000000FF) >> 0;
+	memcpy(&cmd[cmd_len], buf, len);
+
+	t.tx_buf = cmd;
+	t.len = cmd_len + len;
+	spi_message_add_tail(&t, &m);
+
+	err = spi_sync(b53sf->spi, &m);
+	if (err)
+		goto out;
+
+	if (retlen && m.actual_length > cmd_len)
+		*retlen += m.actual_length - cmd_len;
+
+out:
+	kfree(cmd);
+}
+
+static int bcm53xxspiflash_erase(struct spi_nor *nor, loff_t offs)
+{
+	struct bcm53xxsf *b53sf = nor->priv;
+	unsigned char cmd[5];
+	int i;
+
+	i = 0;
+	cmd[i++] = nor->erase_opcode;
+	if (b53sf->mtd.size > 0x1000000)
+		cmd[i++] = (offs & 0xFF000000) >> 24;
+	cmd[i++] = ((offs & 0x00FF0000) >> 16);
+	cmd[i++] = ((offs & 0x0000FF00) >> 8);
+	cmd[i++] = ((offs & 0x000000FF) >> 0);
+
+	return spi_write(b53sf->spi, cmd, i);
+}
+
+static const char *bcm53xxspiflash_chip_name(struct spi_nor *nor)
+{
+	struct bcm53xxsf *b53sf = nor->priv;
+	struct device *dev = &b53sf->spi->dev;
+	unsigned char cmd[4];
+	unsigned char resp[2];
+	int err;
+
+	/* SST and Winbond/NexFlash specific command */
+	cmd[0] = 0x90; /* Read Manufacturer / Device ID */
+	cmd[1] = 0;
+	cmd[2] = 0;
+	cmd[3] = 0;
+	err = spi_write_then_read(b53sf->spi, cmd, 4, resp, 2);
+	if (err < 0) {
+		dev_err(dev, "error reading SPI flash id\n");
+		return ERR_PTR(-EBUSY);
+	}
+	switch (resp[0]) {
+	case 0xef: /* Winbond/NexFlash */
+		switch (resp[1]) {
+		case 0x17:
+			return "w25q128";
+		}
+		dev_err(dev, "Unknown Winbond/NexFlash flash: %02X %02X\n",
+			resp[0], resp[1]);
+		return NULL;
+	}
+
+	/* TODO: Try more ID commands */
+
+	return NULL;
+}
+
+/**************************************************
+ * SPI driver
+ **************************************************/
+
+static int bcm53xxspiflash_probe(struct spi_device *spi)
+{
+	struct bcm53xxsf *b53sf;
+	struct spi_nor *nor;
+	int err;
+
+	b53sf = devm_kzalloc(&spi->dev, sizeof(*b53sf), GFP_KERNEL);
+	if (!b53sf)
+		return -ENOMEM;
+	spi_set_drvdata(spi, b53sf);
+
+	nor = &b53sf->nor;
+	b53sf->spi = spi;
+	b53sf->mtd.priv = &b53sf->nor;
+
+	nor->mtd = &b53sf->mtd;
+	nor->dev = &spi->dev;
+	nor->read_reg = bcm53xxspiflash_read_reg;
+	nor->write_reg = bcm53xxspiflash_write_reg;
+	nor->read = bcm53xxspiflash_read;
+	nor->write = bcm53xxspiflash_write;
+	nor->erase = bcm53xxspiflash_erase;
+	nor->priv = b53sf;
+
+	err = spi_nor_scan(&b53sf->nor, bcm53xxspiflash_chip_name(nor),
+			   SPI_NOR_NORMAL);
+	if (err)
+		return err;
+
+	err = mtd_device_parse_register(&b53sf->mtd, probes, NULL, NULL, 0);
+	if (err)
+		return err;
+
+	return 0;
+}
+
+static int bcm53xxspiflash_remove(struct spi_device *spi)
+{
+	return 0;
+}
+
+static struct spi_driver bcm53xxspiflash_driver = {
+	.driver = {
+		.name	= "bcm53xxspiflash",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= bcm53xxspiflash_probe,
+	.remove		= bcm53xxspiflash_remove,
+};
+
+module_spi_driver(bcm53xxspiflash_driver);
diff --git a/target/linux/bcm53xx/patches-3.14/002-mtd-spi-nor-from-3.18.patch b/target/linux/bcm53xx/patches-3.14/002-mtd-spi-nor-from-3.18.patch
index 6fd5c89fce..873861ab63 100644
--- a/target/linux/bcm53xx/patches-3.14/002-mtd-spi-nor-from-3.18.patch
+++ b/target/linux/bcm53xx/patches-3.14/002-mtd-spi-nor-from-3.18.patch
@@ -1,6 +1,24 @@
 --- 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[]
+@@ -28,6 +28,8 @@
+ 
+ #define JEDEC_MFR(_jedec_id)	((_jedec_id) >> 16)
+ 
++static const struct spi_device_id *spi_nor_match_id(const char *name);
++
+ /*
+  * Read the status register, returning its value in the location
+  * Return the status register value.
+@@ -473,7 +475,7 @@ struct flash_info {
+  * more nor chips.  This current list focusses on newer chips, which
+  * have been converging on command sets which including JEDEC ID.
+  */
+-const struct spi_device_id spi_nor_ids[] = {
++static const struct spi_device_id spi_nor_ids[] = {
+ 	/* Atmel -- some are (confusingly) marketed as "DataFlash" */
+ 	{ "at25fs010",  INFO(0x1f6601, 0, 32 * 1024,   4, SECT_4K) },
+ 	{ "at25fs040",  INFO(0x1f6604, 0, 64 * 1024,   8, SECT_4K) },
+@@ -611,6 +613,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) },
@@ -8,7 +26,7 @@
  
  	/* 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[]
+@@ -623,7 +626,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) },
@@ -16,7 +34,15 @@
  	{ "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
+@@ -637,7 +639,6 @@ const struct spi_device_id spi_nor_ids[]
+ 	{ "cat25128", CAT25_INFO(2048, 8, 64, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
+ 	{ },
+ };
+-EXPORT_SYMBOL_GPL(spi_nor_ids);
+ 
+ static const struct spi_device_id *spi_nor_read_id(struct spi_nor *nor)
+ {
+@@ -671,11 +672,6 @@ static const struct spi_device_id *spi_n
  	return ERR_PTR(-ENODEV);
  }
  
@@ -28,15 +54,21 @@
  static int spi_nor_read(struct mtd_info *mtd, loff_t from, size_t len,
  			size_t *retlen, u_char *buf)
  {
-@@ -920,7 +915,6 @@ int spi_nor_scan(struct spi_nor *nor, co
- 			enum read_mode mode)
+@@ -916,11 +912,10 @@ static int spi_nor_check(struct spi_nor
+ 	return 0;
+ }
+ 
+-int spi_nor_scan(struct spi_nor *nor, const struct spi_device_id *id,
+-			enum read_mode mode)
++int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode)
  {
++	const struct spi_device_id	*id = NULL;
  	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;
-@@ -931,34 +925,12 @@ int spi_nor_scan(struct spi_nor *nor, co
+@@ -931,34 +926,16 @@ int spi_nor_scan(struct spi_nor *nor, co
  	if (ret)
  		return ret;
  
@@ -61,7 +93,10 @@
 -		else
 -			dev_warn(dev, "unrecognized id %s\n", data->type);
 -	}
--
++	id = spi_nor_match_id(name);
++	if (!id)
++		return -ENOENT;
+ 
  	info = (void *)id->driver_data;
  
  	if (info->jedec_id) {
@@ -72,7 +107,7 @@
  		if (IS_ERR(jid)) {
  			return PTR_ERR(jid);
  		} else if (jid != id) {
-@@ -990,11 +962,8 @@ int spi_nor_scan(struct spi_nor *nor, co
+@@ -990,11 +967,8 @@ int spi_nor_scan(struct spi_nor *nor, co
  		write_sr(nor, 0);
  	}
  
@@ -85,7 +120,7 @@
  	mtd->type = MTD_NORFLASH;
  	mtd->writesize = 1;
  	mtd->flags = MTD_CAP_NORFLASH;
-@@ -1018,6 +987,7 @@ int spi_nor_scan(struct spi_nor *nor, co
+@@ -1018,6 +992,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;
  
@@ -93,7 +128,7 @@
  	/* prefer "small sector" erase if possible */
  	if (info->flags & SECT_4K) {
  		nor->erase_opcode = SPINOR_OP_BE_4K;
-@@ -1025,7 +995,9 @@ int spi_nor_scan(struct spi_nor *nor, co
+@@ -1025,7 +1000,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;
@@ -104,6 +139,23 @@
  		nor->erase_opcode = SPINOR_OP_SE;
  		mtd->erasesize = info->sector_size;
  	}
+@@ -1141,7 +1118,7 @@ int spi_nor_scan(struct spi_nor *nor, co
+ }
+ EXPORT_SYMBOL_GPL(spi_nor_scan);
+ 
+-const struct spi_device_id *spi_nor_match_id(char *name)
++static const struct spi_device_id *spi_nor_match_id(const char *name)
+ {
+ 	const struct spi_device_id *id = spi_nor_ids;
+ 
+@@ -1152,7 +1129,6 @@ const struct spi_device_id *spi_nor_matc
+ 	}
+ 	return NULL;
+ }
+-EXPORT_SYMBOL_GPL(spi_nor_match_id);
+ 
+ MODULE_LICENSE("GPL");
+ MODULE_AUTHOR("Huang Shijie <shijie8@gmail.com>");
 --- a/drivers/mtd/spi-nor/Kconfig
 +++ b/drivers/mtd/spi-nor/Kconfig
 @@ -7,6 +7,20 @@ menuconfig MTD_SPI_NOR
@@ -127,3 +179,41 @@
  config SPI_FSL_QUADSPI
  	tristate "Freescale Quad SPI controller"
  	depends on ARCH_MXC
+--- a/include/linux/mtd/spi-nor.h
++++ b/include/linux/mtd/spi-nor.h
+@@ -187,32 +187,17 @@ struct spi_nor {
+ /**
+  * spi_nor_scan() - scan the SPI NOR
+  * @nor:	the spi_nor structure
+- * @id:		the spi_device_id provided by the driver
++ * @name:	the chip type name
+  * @mode:	the read mode supported by the driver
+  *
+  * The drivers can use this fuction to scan the SPI NOR.
+  * In the scanning, it will try to get all the necessary information to
+  * fill the mtd_info{} and the spi_nor{}.
+  *
+- * The board may assigns a spi_device_id with @id which be used to compared with
+- * the spi_device_id detected by the scanning.
++ * The chip type name can be provided through the @name parameter.
+  *
+  * Return: 0 for success, others for failure.
+  */
+-int spi_nor_scan(struct spi_nor *nor, const struct spi_device_id *id,
+-			enum read_mode mode);
+-extern const struct spi_device_id spi_nor_ids[];
+-
+-/**
+- * spi_nor_match_id() - find the spi_device_id by the name
+- * @name:	the name of the spi_device_id
+- *
+- * The drivers use this function to find the spi_device_id
+- * specified by the @name.
+- *
+- * Return: returns the right spi_device_id pointer on success,
+- *         and returns NULL on failure.
+- */
+-const struct spi_device_id *spi_nor_match_id(char *name);
++int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode);
+ 
+ #endif
diff --git a/target/linux/bcm53xx/patches-3.14/003-mtd-spi-nor-from-3.19.patch b/target/linux/bcm53xx/patches-3.14/003-mtd-spi-nor-from-3.19.patch
new file mode 100644
index 0000000000..5451b9c6a4
--- /dev/null
+++ b/target/linux/bcm53xx/patches-3.14/003-mtd-spi-nor-from-3.19.patch
@@ -0,0 +1,662 @@
+--- a/drivers/mtd/spi-nor/spi-nor.c
++++ b/drivers/mtd/spi-nor/spi-nor.c
+@@ -26,7 +26,38 @@
+ /* Define max times to check status register before we give up. */
+ #define	MAX_READY_WAIT_JIFFIES	(40 * HZ) /* M25P16 specs 40s max chip erase */
+ 
+-#define JEDEC_MFR(_jedec_id)	((_jedec_id) >> 16)
++#define SPI_NOR_MAX_ID_LEN	6
++
++struct flash_info {
++	/*
++	 * This array stores the ID bytes.
++	 * The first three bytes are the JEDIC ID.
++	 * JEDEC ID zero means "no ID" (mostly older chips).
++	 */
++	u8		id[SPI_NOR_MAX_ID_LEN];
++	u8		id_len;
++
++	/* The size listed here is what works with SPINOR_OP_SE, which isn't
++	 * necessarily called a "sector" by the vendor.
++	 */
++	unsigned	sector_size;
++	u16		n_sectors;
++
++	u16		page_size;
++	u16		addr_width;
++
++	u16		flags;
++#define	SECT_4K			0x01	/* SPINOR_OP_BE_4K works uniformly */
++#define	SPI_NOR_NO_ERASE	0x02	/* No erase command needed */
++#define	SST_WRITE		0x04	/* use SST byte programming */
++#define	SPI_NOR_NO_FR		0x08	/* Can't do fastread */
++#define	SECT_4K_PMC		0x10	/* SPINOR_OP_BE_4K_PMC works uniformly */
++#define	SPI_NOR_DUAL_READ	0x20    /* Flash supports Dual Read */
++#define	SPI_NOR_QUAD_READ	0x40    /* Flash supports Quad Read */
++#define	USE_FSR			0x80	/* use flag status register */
++};
++
++#define JEDEC_MFR(info)	((info)->id[0])
+ 
+ static const struct spi_device_id *spi_nor_match_id(const char *name);
+ 
+@@ -98,7 +129,7 @@ static inline int spi_nor_read_dummy_cyc
+ 	case SPI_NOR_FAST:
+ 	case SPI_NOR_DUAL:
+ 	case SPI_NOR_QUAD:
+-		return 1;
++		return 8;
+ 	case SPI_NOR_NORMAL:
+ 		return 0;
+ 	}
+@@ -138,13 +169,14 @@ static inline struct spi_nor *mtd_to_spi
+ }
+ 
+ /* Enable/disable 4-byte addressing mode. */
+-static inline int set_4byte(struct spi_nor *nor, u32 jedec_id, int enable)
++static inline int set_4byte(struct spi_nor *nor, struct flash_info *info,
++			    int enable)
+ {
+ 	int status;
+ 	bool need_wren = false;
+ 	u8 cmd;
+ 
+-	switch (JEDEC_MFR(jedec_id)) {
++	switch (JEDEC_MFR(info)) {
+ 	case CFI_MFR_ST: /* Micron, actually */
+ 		/* Some Micron need WREN command; all will accept it */
+ 		need_wren = true;
+@@ -165,81 +197,74 @@ 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 fsr;
++	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 timeout = 0, ret;
+ 
+ 	deadline = jiffies + MAX_READY_WAIT_JIFFIES;
+ 
+-	do {
++	while (!timeout) {
++		if (time_after_eq(jiffies, deadline))
++			timeout = 1;
++
++		ret = spi_nor_ready(nor);
++		if (ret < 0)
++			return ret;
++		if (ret)
++			return 0;
++
+ 		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;
+-		}
+-	} while (!time_after_eq(jiffies, deadline));
++	dev_err(nor->dev, "flash operation timed out\n");
+ 
+ 	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);
+ }
+ 
+@@ -294,11 +319,17 @@ static int spi_nor_erase(struct mtd_info
+ 
+ 	/* whole-chip erase? */
+ 	if (len == mtd->size) {
++		write_enable(nor);
++
+ 		if (erase_chip(nor)) {
+ 			ret = -EIO;
+ 			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.
+@@ -307,6 +338,8 @@ static int spi_nor_erase(struct mtd_info
+ 	/* "sector"-at-a-time erase */
+ 	} else {
+ 		while (len) {
++			write_enable(nor);
++
+ 			if (nor->erase(nor, addr)) {
+ 				ret = -EIO;
+ 				goto erase_err;
+@@ -314,9 +347,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;
+@@ -341,11 +380,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))
+@@ -388,11 +422,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))
+@@ -424,38 +453,34 @@ err:
+ 	return ret;
+ }
+ 
+-struct flash_info {
+-	/* JEDEC id zero means "no ID" (most older chips); otherwise it has
+-	 * a high byte of zero plus three data bytes: the manufacturer id,
+-	 * then a two byte device id.
+-	 */
+-	u32		jedec_id;
+-	u16             ext_id;
+-
+-	/* The size listed here is what works with SPINOR_OP_SE, which isn't
+-	 * necessarily called a "sector" by the vendor.
+-	 */
+-	unsigned	sector_size;
+-	u16		n_sectors;
+-
+-	u16		page_size;
+-	u16		addr_width;
+-
+-	u16		flags;
+-#define	SECT_4K			0x01	/* SPINOR_OP_BE_4K works uniformly */
+-#define	SPI_NOR_NO_ERASE	0x02	/* No erase command needed */
+-#define	SST_WRITE		0x04	/* use SST byte programming */
+-#define	SPI_NOR_NO_FR		0x08	/* Can't do fastread */
+-#define	SECT_4K_PMC		0x10	/* SPINOR_OP_BE_4K_PMC works uniformly */
+-#define	SPI_NOR_DUAL_READ	0x20    /* Flash supports Dual Read */
+-#define	SPI_NOR_QUAD_READ	0x40    /* Flash supports Quad Read */
+-#define	USE_FSR			0x80	/* use flag status register */
+-};
+-
++/* Used when the "_ext_id" is two bytes at most */
+ #define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags)	\
+ 	((kernel_ulong_t)&(struct flash_info) {				\
+-		.jedec_id = (_jedec_id),				\
+-		.ext_id = (_ext_id),					\
++		.id = {							\
++			((_jedec_id) >> 16) & 0xff,			\
++			((_jedec_id) >> 8) & 0xff,			\
++			(_jedec_id) & 0xff,				\
++			((_ext_id) >> 8) & 0xff,			\
++			(_ext_id) & 0xff,				\
++			},						\
++		.id_len = (!(_jedec_id) ? 0 : (3 + ((_ext_id) ? 2 : 0))),	\
++		.sector_size = (_sector_size),				\
++		.n_sectors = (_n_sectors),				\
++		.page_size = 256,					\
++		.flags = (_flags),					\
++	})
++
++#define INFO6(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags)	\
++	((kernel_ulong_t)&(struct flash_info) {				\
++		.id = {							\
++			((_jedec_id) >> 16) & 0xff,			\
++			((_jedec_id) >> 8) & 0xff,			\
++			(_jedec_id) & 0xff,				\
++			((_ext_id) >> 16) & 0xff,			\
++			((_ext_id) >> 8) & 0xff,			\
++			(_ext_id) & 0xff,				\
++			},						\
++		.id_len = 6,						\
+ 		.sector_size = (_sector_size),				\
+ 		.n_sectors = (_n_sectors),				\
+ 		.page_size = 256,					\
+@@ -507,6 +532,9 @@ static const struct spi_device_id spi_no
+ 	{ "mr25h256", CAT25_INFO( 32 * 1024, 1, 256, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
+ 	{ "mr25h10",  CAT25_INFO(128 * 1024, 1, 256, 3, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
+ 
++	/* Fujitsu */
++	{ "mb85rs1mt", INFO(0x047f27, 0, 128 * 1024, 1, SPI_NOR_NO_ERASE) },
++
+ 	/* GigaDevice */
+ 	{ "gd25q32", INFO(0xc84016, 0, 64 * 1024,  64, SECT_4K) },
+ 	{ "gd25q64", INFO(0xc84017, 0, 64 * 1024, 128, SECT_4K) },
+@@ -532,6 +560,7 @@ static const struct spi_device_id spi_no
+ 	{ "mx66l1g55g",  INFO(0xc2261b, 0, 64 * 1024, 2048, SPI_NOR_QUAD_READ) },
+ 
+ 	/* Micron */
++	{ "n25q032",	 INFO(0x20ba16, 0, 64 * 1024,   64, 0) },
+ 	{ "n25q064",     INFO(0x20ba17, 0, 64 * 1024,  128, 0) },
+ 	{ "n25q128a11",  INFO(0x20bb18, 0, 64 * 1024,  256, 0) },
+ 	{ "n25q128a13",  INFO(0x20ba18, 0, 64 * 1024,  256, 0) },
+@@ -556,6 +585,7 @@ static const struct spi_device_id spi_no
+ 	{ "s70fl01gs",  INFO(0x010221, 0x4d00, 256 * 1024, 256, 0) },
+ 	{ "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024,  64, 0) },
+ 	{ "s25sl12801", INFO(0x012018, 0x0301,  64 * 1024, 256, 0) },
++	{ "s25fl128s",	INFO6(0x012018, 0x4d0180, 64 * 1024, 256, SPI_NOR_QUAD_READ) },
+ 	{ "s25fl129p0", INFO(0x012018, 0x4d00, 256 * 1024,  64, 0) },
+ 	{ "s25fl129p1", INFO(0x012018, 0x4d01,  64 * 1024, 256, 0) },
+ 	{ "s25sl004a",  INFO(0x010212,      0,  64 * 1024,   8, 0) },
+@@ -577,6 +607,7 @@ static const struct spi_device_id spi_no
+ 	{ "sst25wf010",  INFO(0xbf2502, 0, 64 * 1024,  2, SECT_4K | SST_WRITE) },
+ 	{ "sst25wf020",  INFO(0xbf2503, 0, 64 * 1024,  4, SECT_4K | SST_WRITE) },
+ 	{ "sst25wf040",  INFO(0xbf2504, 0, 64 * 1024,  8, SECT_4K | SST_WRITE) },
++	{ "sst25wf080",  INFO(0xbf2505, 0, 64 * 1024, 16, SECT_4K | SST_WRITE) },
+ 
+ 	/* ST Microelectronics -- newer production may have feature updates */
+ 	{ "m25p05",  INFO(0x202010,  0,  32 * 1024,   2, 0) },
+@@ -588,7 +619,6 @@ static const struct spi_device_id spi_no
+ 	{ "m25p32",  INFO(0x202016,  0,  64 * 1024,  64, 0) },
+ 	{ "m25p64",  INFO(0x202017,  0,  64 * 1024, 128, 0) },
+ 	{ "m25p128", INFO(0x202018,  0, 256 * 1024,  64, 0) },
+-	{ "n25q032", INFO(0x20ba16,  0,  64 * 1024,  64, 0) },
+ 
+ 	{ "m25p05-nonjedec",  INFO(0, 0,  32 * 1024,   2, 0) },
+ 	{ "m25p10-nonjedec",  INFO(0, 0,  32 * 1024,   4, 0) },
+@@ -643,32 +673,24 @@ static const struct spi_device_id spi_no
+ static const struct spi_device_id *spi_nor_read_id(struct spi_nor *nor)
+ {
+ 	int			tmp;
+-	u8			id[5];
+-	u32			jedec;
+-	u16                     ext_jedec;
++	u8			id[SPI_NOR_MAX_ID_LEN];
+ 	struct flash_info	*info;
+ 
+-	tmp = nor->read_reg(nor, SPINOR_OP_RDID, id, 5);
++	tmp = nor->read_reg(nor, SPINOR_OP_RDID, id, SPI_NOR_MAX_ID_LEN);
+ 	if (tmp < 0) {
+ 		dev_dbg(nor->dev, " error %d reading JEDEC ID\n", tmp);
+ 		return ERR_PTR(tmp);
+ 	}
+-	jedec = id[0];
+-	jedec = jedec << 8;
+-	jedec |= id[1];
+-	jedec = jedec << 8;
+-	jedec |= id[2];
+-
+-	ext_jedec = id[3] << 8 | id[4];
+ 
+ 	for (tmp = 0; tmp < ARRAY_SIZE(spi_nor_ids) - 1; tmp++) {
+ 		info = (void *)spi_nor_ids[tmp].driver_data;
+-		if (info->jedec_id == jedec) {
+-			if (info->ext_id == 0 || info->ext_id == ext_jedec)
++		if (info->id_len) {
++			if (!memcmp(info->id, id, info->id_len))
+ 				return &spi_nor_ids[tmp];
+ 		}
+ 	}
+-	dev_err(nor->dev, "unrecognized JEDEC id %06x\n", jedec);
++	dev_err(nor->dev, "unrecognized JEDEC id bytes: %02x, %2x, %2x\n",
++		id[0], id[1], id[2]);
+ 	return ERR_PTR(-ENODEV);
+ }
+ 
+@@ -703,11 +725,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;
+@@ -719,7 +736,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;
+ 	}
+@@ -731,7 +748,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;
+@@ -740,7 +757,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;
+ 
+@@ -751,7 +768,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);
+@@ -779,11 +796,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);
+@@ -802,16 +814,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)
+@@ -824,7 +840,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);
+@@ -874,11 +890,11 @@ static int spansion_quad_enable(struct s
+ 	return 0;
+ }
+ 
+-static int set_quad_mode(struct spi_nor *nor, u32 jedec_id)
++static int set_quad_mode(struct spi_nor *nor, struct flash_info *info)
+ {
+ 	int status;
+ 
+-	switch (JEDEC_MFR(jedec_id)) {
++	switch (JEDEC_MFR(info)) {
+ 	case CFI_MFR_MACRONIX:
+ 		status = macronix_quad_enable(nor);
+ 		if (status) {
+@@ -904,11 +920,6 @@ static int spi_nor_check(struct spi_nor
+ 		return -EINVAL;
+ 	}
+ 
+-	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;
+ }
+ 
+@@ -926,16 +937,24 @@ int spi_nor_scan(struct spi_nor *nor, co
+ 	if (ret)
+ 		return ret;
+ 
+-	id = spi_nor_match_id(name);
+-	if (!id)
++	/* Try to auto-detect if chip name wasn't specified */
++	if (!name)
++		id = spi_nor_read_id(nor);
++	else
++		id = spi_nor_match_id(name);
++	if (IS_ERR_OR_NULL(id))
+ 		return -ENOENT;
+ 
+ 	info = (void *)id->driver_data;
+ 
+-	if (info->jedec_id) {
++	/*
++	 * If caller has specified name of flash model that can normally be
++	 * detected using JEDEC, let's verify it.
++	 */
++	if (name && info->id_len) {
+ 		const struct spi_device_id *jid;
+ 
+-		jid = nor->read_id(nor);
++		jid = spi_nor_read_id(nor);
+ 		if (IS_ERR(jid)) {
+ 			return PTR_ERR(jid);
+ 		} else if (jid != id) {
+@@ -960,9 +979,9 @@ int spi_nor_scan(struct spi_nor *nor, co
+ 	 * up with the software protection bits set
+ 	 */
+ 
+-	if (JEDEC_MFR(info->jedec_id) == CFI_MFR_ATMEL ||
+-	    JEDEC_MFR(info->jedec_id) == CFI_MFR_INTEL ||
+-	    JEDEC_MFR(info->jedec_id) == CFI_MFR_SST) {
++	if (JEDEC_MFR(info) == CFI_MFR_ATMEL ||
++	    JEDEC_MFR(info) == CFI_MFR_INTEL ||
++	    JEDEC_MFR(info) == CFI_MFR_SST) {
+ 		write_enable(nor);
+ 		write_sr(nor, 0);
+ 	}
+@@ -977,7 +996,7 @@ int spi_nor_scan(struct spi_nor *nor, co
+ 	mtd->_read = spi_nor_read;
+ 
+ 	/* nor protection support for STmicro chips */
+-	if (JEDEC_MFR(info->jedec_id) == CFI_MFR_ST) {
++	if (JEDEC_MFR(info) == CFI_MFR_ST) {
+ 		mtd->_lock = spi_nor_lock;
+ 		mtd->_unlock = spi_nor_unlock;
+ 	}
+@@ -988,9 +1007,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 */
+@@ -1031,7 +1049,7 @@ int spi_nor_scan(struct spi_nor *nor, co
+ 
+ 	/* Quad/Dual-read mode takes precedence over fast/normal */
+ 	if (mode == SPI_NOR_QUAD && info->flags & SPI_NOR_QUAD_READ) {
+-		ret = set_quad_mode(nor, info->jedec_id);
++		ret = set_quad_mode(nor, info);
+ 		if (ret) {
+ 			dev_err(dev, "quad mode not supported\n");
+ 			return ret;
+@@ -1067,7 +1085,7 @@ int spi_nor_scan(struct spi_nor *nor, co
+ 	else if (mtd->size > 0x1000000) {
+ 		/* enable 4-byte addressing if the device exceeds 16MiB */
+ 		nor->addr_width = 4;
+-		if (JEDEC_MFR(info->jedec_id) == CFI_MFR_AMD) {
++		if (JEDEC_MFR(info) == CFI_MFR_AMD) {
+ 			/* Dedicated 4-byte command set */
+ 			switch (nor->flash_read) {
+ 			case SPI_NOR_QUAD:
+@@ -1088,7 +1106,7 @@ int spi_nor_scan(struct spi_nor *nor, co
+ 			nor->erase_opcode = SPINOR_OP_SE_4B;
+ 			mtd->erasesize = info->sector_size;
+ 		} else
+-			set_4byte(nor, info->jedec_id, 1);
++			set_4byte(nor, info, 1);
+ 	} else {
+ 		nor->addr_width = 3;
+ 	}
+--- 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
+@@ -139,9 +144,6 @@ enum spi_nor_ops {
+  * @write_xfer:		[OPTIONAL] the writefundamental primitive
+  * @read_reg:		[DRIVER-SPECIFIC] read out the register
+  * @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 +162,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];
+ 
+@@ -172,8 +175,6 @@ struct spi_nor {
+ 	int (*read_reg)(struct spi_nor *nor, u8 opcode, u8 *buf, int len);
+ 	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);
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
deleted file mode 100644
index 6cc77528e0..0000000000
--- a/target/linux/bcm53xx/patches-3.14/402-mtd-spi-nor-allow-NULL-as-spi_device_id-in-spi_nor_s.patch
+++ /dev/null
@@ -1,46 +0,0 @@
---- 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
deleted file mode 100644
index 79a5131314..0000000000
--- a/target/linux/bcm53xx/patches-3.14/403-mtd-spi-nor-refactor-wait-till-ready.patch
+++ /dev/null
@@ -1,374 +0,0 @@
---- 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);
diff --git a/target/linux/bcm53xx/patches-3.14/404-mtd-bcm53xxspiflash-new-driver-for-SPI-flahes-on-Bro.patch b/target/linux/bcm53xx/patches-3.14/404-mtd-bcm53xxspiflash-new-driver-for-SPI-flahes-on-Bro.patch
index 9a9d903f82..41ef3b300e 100644
--- a/target/linux/bcm53xx/patches-3.14/404-mtd-bcm53xxspiflash-new-driver-for-SPI-flahes-on-Bro.patch
+++ b/target/linux/bcm53xx/patches-3.14/404-mtd-bcm53xxspiflash-new-driver-for-SPI-flahes-on-Bro.patch
@@ -17,247 +17,3 @@
  obj-$(CONFIG_MTD_SPI_NOR)	+= spi-nor.o
  obj-$(CONFIG_SPI_FSL_QUADSPI)	+= fsl-quadspi.o
 +obj-$(CONFIG_MTD_SPI_BCM53XXSPIFLASH)	+= bcm53xxspiflash.o
---- /dev/null
-+++ b/drivers/mtd/spi-nor/bcm53xxspiflash.c
-@@ -0,0 +1,241 @@
-+#include <linux/module.h>
-+#include <linux/delay.h>
-+#include <linux/spi/spi.h>
-+#include <linux/mtd/spi-nor.h>
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/cfi.h>
-+
-+static const char * const probes[] = { "bcm47xxpart", NULL };
-+
-+struct bcm53xxsf {
-+	struct spi_device *spi;
-+	struct mtd_info mtd;
-+	struct spi_nor nor;
-+};
-+
-+/**************************************************
-+ * spi-nor API
-+ **************************************************/
-+
-+static int bcm53xxspiflash_read_reg(struct spi_nor *nor, u8 opcode, u8 *buf,
-+				   int len)
-+{
-+	struct bcm53xxsf *b53sf = nor->priv;
-+
-+	return spi_write_then_read(b53sf->spi, &opcode, 1, buf, len);
-+}
-+
-+static int bcm53xxspiflash_write_reg(struct spi_nor *nor, u8 opcode, u8 *buf,
-+				     int len, int write_enable)
-+{
-+	struct bcm53xxsf *b53sf = nor->priv;
-+	u8 *cmd = kzalloc(len + 1, GFP_KERNEL);
-+	int err;
-+
-+	if (!cmd)
-+		return -ENOMEM;
-+
-+	cmd[0] = opcode;
-+	memcpy(&cmd[1], buf, len);
-+	err = spi_write(b53sf->spi, cmd, len + 1);
-+
-+	kfree(cmd);
-+
-+	return err;
-+}
-+
-+static int bcm53xxspiflash_read(struct spi_nor *nor, loff_t from, size_t len,
-+				size_t *retlen, u_char *buf)
-+{
-+	struct bcm53xxsf *b53sf = nor->priv;
-+	struct spi_message m;
-+	struct spi_transfer t[2] = { { 0 }, { 0 } };
-+	unsigned char cmd[5];
-+	int cmd_len = 0;
-+	int err;
-+
-+	spi_message_init(&m);
-+
-+	cmd[cmd_len++] = SPINOR_OP_READ;
-+	if (b53sf->mtd.size > 0x1000000)
-+		cmd[cmd_len++] = (from & 0xFF000000) >> 24;
-+	cmd[cmd_len++] = (from & 0x00FF0000) >> 16;
-+	cmd[cmd_len++] = (from & 0x0000FF00) >> 8;
-+	cmd[cmd_len++] = (from & 0x000000FF) >> 0;
-+
-+	t[0].tx_buf = cmd;
-+	t[0].len = cmd_len;
-+	spi_message_add_tail(&t[0], &m);
-+
-+	t[1].rx_buf = buf;
-+	t[1].len = len;
-+	spi_message_add_tail(&t[1], &m);
-+
-+	err = spi_sync(b53sf->spi, &m);
-+	if (err)
-+		return err;
-+
-+	if (retlen && m.actual_length > cmd_len)
-+		*retlen = m.actual_length - cmd_len;
-+
-+	return 0;
-+}
-+
-+static void bcm53xxspiflash_write(struct spi_nor *nor, loff_t to, size_t len,
-+				  size_t *retlen, const u_char *buf)
-+{
-+	struct bcm53xxsf *b53sf = nor->priv;
-+	struct spi_message m;
-+	struct spi_transfer t = { 0 };
-+	u8 *cmd = kzalloc(len + 5, GFP_KERNEL);
-+	int cmd_len = 0;
-+	int err;
-+
-+	if (!cmd)
-+		return;
-+
-+	spi_message_init(&m);
-+
-+	cmd[cmd_len++] = nor->program_opcode;
-+	if (b53sf->mtd.size > 0x1000000)
-+		cmd[cmd_len++] = (to & 0xFF000000) >> 24;
-+	cmd[cmd_len++] = (to & 0x00FF0000) >> 16;
-+	cmd[cmd_len++] = (to & 0x0000FF00) >> 8;
-+	cmd[cmd_len++] = (to & 0x000000FF) >> 0;
-+	memcpy(&cmd[cmd_len], buf, len);
-+
-+	t.tx_buf = cmd;
-+	t.len = cmd_len + len;
-+	spi_message_add_tail(&t, &m);
-+
-+	err = spi_sync(b53sf->spi, &m);
-+	if (err)
-+		goto out;
-+
-+	if (retlen && m.actual_length > cmd_len)
-+		*retlen += m.actual_length - cmd_len;
-+
-+out:
-+	kfree(cmd);
-+}
-+
-+static int bcm53xxspiflash_erase(struct spi_nor *nor, loff_t offs)
-+{
-+	struct bcm53xxsf *b53sf = nor->priv;
-+	unsigned char cmd[5];
-+	int i;
-+
-+	i = 0;
-+	cmd[i++] = nor->erase_opcode;
-+	if (b53sf->mtd.size > 0x1000000)
-+		cmd[i++] = (offs & 0xFF000000) >> 24;
-+	cmd[i++] = ((offs & 0x00FF0000) >> 16);
-+	cmd[i++] = ((offs & 0x0000FF00) >> 8);
-+	cmd[i++] = ((offs & 0x000000FF) >> 0);
-+
-+	return spi_write(b53sf->spi, cmd, i);
-+}
-+
-+static const struct spi_device_id *bcm53xxspiflash_read_id(struct spi_nor *nor)
-+{
-+	struct bcm53xxsf *b53sf = nor->priv;
-+	struct device *dev = &b53sf->spi->dev;
-+	const struct spi_device_id *id;
-+	unsigned char cmd[4];
-+	unsigned char resp[2];
-+	char *name = NULL;
-+	int err;
-+
-+	/* SST and Winbond/NexFlash specific command */
-+	cmd[0] = 0x90; /* Read Manufacturer / Device ID */
-+	cmd[1] = 0;
-+	cmd[2] = 0;
-+	cmd[3] = 0;
-+	err = spi_write_then_read(b53sf->spi, cmd, 4, resp, 2);
-+	if (err < 0) {
-+		dev_err(dev, "error reading SPI flash id\n");
-+		return ERR_PTR(-EBUSY);
-+	}
-+	switch (resp[0]) {
-+	case 0xef: /* Winbond/NexFlash */
-+		switch (resp[1]) {
-+		case 0x17:
-+			name = "w25q128";
-+			break;
-+		}
-+		if (!name) {
-+			dev_err(dev, "Unknown Winbond/NexFlash flash: %02X %02X\n",
-+				resp[0], resp[1]);
-+			return ERR_PTR(-ENOTSUPP);
-+		}
-+		goto found_name;
-+	}
-+
-+	/* TODO: Try more ID commands */
-+
-+	return ERR_PTR(-ENODEV);
-+
-+found_name:
-+	id = spi_nor_match_id(name);
-+	if (!id) {
-+		dev_err(dev, "No matching entry for %s flash\n", name);
-+		return ERR_PTR(-ENOENT);
-+	}
-+
-+	return id;
-+}
-+
-+/**************************************************
-+ * SPI driver
-+ **************************************************/
-+
-+static int bcm53xxspiflash_probe(struct spi_device *spi)
-+{
-+	struct bcm53xxsf *b53sf;
-+	int err;
-+
-+	b53sf = devm_kzalloc(&spi->dev, sizeof(*b53sf), GFP_KERNEL);
-+	if (!b53sf)
-+		return -ENOMEM;
-+	spi_set_drvdata(spi, b53sf);
-+
-+	b53sf->spi = spi;
-+
-+	b53sf->mtd.priv = &b53sf->nor;
-+
-+	b53sf->nor.mtd = &b53sf->mtd;
-+	b53sf->nor.dev = &spi->dev;
-+	b53sf->nor.read_reg = bcm53xxspiflash_read_reg;
-+	b53sf->nor.write_reg = bcm53xxspiflash_write_reg;
-+	b53sf->nor.read = bcm53xxspiflash_read;
-+	b53sf->nor.write = bcm53xxspiflash_write;
-+	b53sf->nor.erase = bcm53xxspiflash_erase;
-+	b53sf->nor.read_id = bcm53xxspiflash_read_id;
-+	b53sf->nor.priv = b53sf;
-+
-+	err = spi_nor_scan(&b53sf->nor, NULL, SPI_NOR_NORMAL);
-+	if (err)
-+		return err;
-+
-+	err = mtd_device_parse_register(&b53sf->mtd, probes, NULL, NULL, 0);
-+	if (err)
-+		return err;
-+
-+	return 0;
-+}
-+
-+static int bcm53xxspiflash_remove(struct spi_device *spi)
-+{
-+	return 0;
-+}
-+
-+static struct spi_driver bcm53xxspiflash_driver = {
-+	.driver = {
-+		.name	= "bcm53xxspiflash",
-+		.owner	= THIS_MODULE,
-+	},
-+	.probe		= bcm53xxspiflash_probe,
-+	.remove		= bcm53xxspiflash_remove,
-+};
-+
-+module_spi_driver(bcm53xxspiflash_driver);
diff --git a/target/linux/bcm53xx/patches-3.14/405-mtd-bcm53xxspiflash-try-using-JEDEC-as-one-of-method.patch b/target/linux/bcm53xx/patches-3.14/405-mtd-bcm53xxspiflash-try-using-JEDEC-as-one-of-method.patch
deleted file mode 100644
index f2bb0542b9..0000000000
--- a/target/linux/bcm53xx/patches-3.14/405-mtd-bcm53xxspiflash-try-using-JEDEC-as-one-of-method.patch
+++ /dev/null
@@ -1,42 +0,0 @@
---- a/drivers/mtd/spi-nor/bcm53xxspiflash.c
-+++ b/drivers/mtd/spi-nor/bcm53xxspiflash.c
-@@ -173,7 +173,8 @@ static const struct spi_device_id *bcm53
- 
- 	/* TODO: Try more ID commands */
- 
--	return ERR_PTR(-ENODEV);
-+	/* Some chips used by Broadcom may actually support JEDEC */
-+	return spi_nor_read_id(nor);
- 
- found_name:
- 	id = spi_nor_match_id(name);
---- a/drivers/mtd/spi-nor/spi-nor.c
-+++ b/drivers/mtd/spi-nor/spi-nor.c
-@@ -629,7 +629,7 @@ const struct spi_device_id spi_nor_ids[]
- };
- EXPORT_SYMBOL_GPL(spi_nor_ids);
- 
--static const struct spi_device_id *spi_nor_read_id(struct spi_nor *nor)
-+const struct spi_device_id *spi_nor_read_id(struct spi_nor *nor)
- {
- 	int			tmp;
- 	u8			id[5];
-@@ -660,6 +660,7 @@ static const struct spi_device_id *spi_n
- 	dev_err(nor->dev, "unrecognized JEDEC id %06x\n", jedec);
- 	return ERR_PTR(-ENODEV);
- }
-+EXPORT_SYMBOL_GPL(spi_nor_read_id);
- 
- static int spi_nor_read(struct mtd_info *mtd, loff_t from, size_t len,
- 			size_t *retlen, u_char *buf)
---- a/include/linux/mtd/spi-nor.h
-+++ b/include/linux/mtd/spi-nor.h
-@@ -188,6 +188,8 @@ struct spi_nor {
- 	void *priv;
- };
- 
-+const struct spi_device_id *spi_nor_read_id(struct spi_nor *nor);
-+
- /**
-  * spi_nor_scan() - scan the SPI NOR
-  * @nor:	the spi_nor structure
diff --git a/target/linux/bcm53xx/patches-3.18/003-mtd-spi-nor-from-3.19.patch b/target/linux/bcm53xx/patches-3.18/003-mtd-spi-nor-from-3.19.patch
new file mode 100644
index 0000000000..2e5fa10a60
--- /dev/null
+++ b/target/linux/bcm53xx/patches-3.18/003-mtd-spi-nor-from-3.19.patch
@@ -0,0 +1,662 @@
+--- a/drivers/mtd/spi-nor/spi-nor.c
++++ b/drivers/mtd/spi-nor/spi-nor.c
+@@ -26,7 +26,38 @@
+ /* Define max times to check status register before we give up. */
+ #define	MAX_READY_WAIT_JIFFIES	(40 * HZ) /* M25P16 specs 40s max chip erase */
+ 
+-#define JEDEC_MFR(_jedec_id)	((_jedec_id) >> 16)
++#define SPI_NOR_MAX_ID_LEN	6
++
++struct flash_info {
++	/*
++	 * This array stores the ID bytes.
++	 * The first three bytes are the JEDIC ID.
++	 * JEDEC ID zero means "no ID" (mostly older chips).
++	 */
++	u8		id[SPI_NOR_MAX_ID_LEN];
++	u8		id_len;
++
++	/* The size listed here is what works with SPINOR_OP_SE, which isn't
++	 * necessarily called a "sector" by the vendor.
++	 */
++	unsigned	sector_size;
++	u16		n_sectors;
++
++	u16		page_size;
++	u16		addr_width;
++
++	u16		flags;
++#define	SECT_4K			0x01	/* SPINOR_OP_BE_4K works uniformly */
++#define	SPI_NOR_NO_ERASE	0x02	/* No erase command needed */
++#define	SST_WRITE		0x04	/* use SST byte programming */
++#define	SPI_NOR_NO_FR		0x08	/* Can't do fastread */
++#define	SECT_4K_PMC		0x10	/* SPINOR_OP_BE_4K_PMC works uniformly */
++#define	SPI_NOR_DUAL_READ	0x20    /* Flash supports Dual Read */
++#define	SPI_NOR_QUAD_READ	0x40    /* Flash supports Quad Read */
++#define	USE_FSR			0x80	/* use flag status register */
++};
++
++#define JEDEC_MFR(info)	((info)->id[0])
+ 
+ static const struct spi_device_id *spi_nor_match_id(const char *name);
+ 
+@@ -98,7 +129,7 @@ static inline int spi_nor_read_dummy_cyc
+ 	case SPI_NOR_FAST:
+ 	case SPI_NOR_DUAL:
+ 	case SPI_NOR_QUAD:
+-		return 1;
++		return 8;
+ 	case SPI_NOR_NORMAL:
+ 		return 0;
+ 	}
+@@ -138,13 +169,14 @@ static inline struct spi_nor *mtd_to_spi
+ }
+ 
+ /* Enable/disable 4-byte addressing mode. */
+-static inline int set_4byte(struct spi_nor *nor, u32 jedec_id, int enable)
++static inline int set_4byte(struct spi_nor *nor, struct flash_info *info,
++			    int enable)
+ {
+ 	int status;
+ 	bool need_wren = false;
+ 	u8 cmd;
+ 
+-	switch (JEDEC_MFR(jedec_id)) {
++	switch (JEDEC_MFR(info)) {
+ 	case CFI_MFR_ST: /* Micron, actually */
+ 		/* Some Micron need WREN command; all will accept it */
+ 		need_wren = true;
+@@ -165,81 +197,74 @@ 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 fsr;
++	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 timeout = 0, ret;
+ 
+ 	deadline = jiffies + MAX_READY_WAIT_JIFFIES;
+ 
+-	do {
++	while (!timeout) {
++		if (time_after_eq(jiffies, deadline))
++			timeout = 1;
++
++		ret = spi_nor_ready(nor);
++		if (ret < 0)
++			return ret;
++		if (ret)
++			return 0;
++
+ 		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;
+-		}
+-	} while (!time_after_eq(jiffies, deadline));
++	dev_err(nor->dev, "flash operation timed out\n");
+ 
+ 	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);
+ }
+ 
+@@ -294,11 +319,17 @@ static int spi_nor_erase(struct mtd_info
+ 
+ 	/* whole-chip erase? */
+ 	if (len == mtd->size) {
++		write_enable(nor);
++
+ 		if (erase_chip(nor)) {
+ 			ret = -EIO;
+ 			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.
+@@ -307,6 +338,8 @@ static int spi_nor_erase(struct mtd_info
+ 	/* "sector"-at-a-time erase */
+ 	} else {
+ 		while (len) {
++			write_enable(nor);
++
+ 			if (nor->erase(nor, addr)) {
+ 				ret = -EIO;
+ 				goto erase_err;
+@@ -314,9 +347,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;
+@@ -341,11 +380,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))
+@@ -388,11 +422,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))
+@@ -424,38 +453,34 @@ err:
+ 	return ret;
+ }
+ 
+-struct flash_info {
+-	/* JEDEC id zero means "no ID" (most older chips); otherwise it has
+-	 * a high byte of zero plus three data bytes: the manufacturer id,
+-	 * then a two byte device id.
+-	 */
+-	u32		jedec_id;
+-	u16             ext_id;
+-
+-	/* The size listed here is what works with SPINOR_OP_SE, which isn't
+-	 * necessarily called a "sector" by the vendor.
+-	 */
+-	unsigned	sector_size;
+-	u16		n_sectors;
+-
+-	u16		page_size;
+-	u16		addr_width;
+-
+-	u16		flags;
+-#define	SECT_4K			0x01	/* SPINOR_OP_BE_4K works uniformly */
+-#define	SPI_NOR_NO_ERASE	0x02	/* No erase command needed */
+-#define	SST_WRITE		0x04	/* use SST byte programming */
+-#define	SPI_NOR_NO_FR		0x08	/* Can't do fastread */
+-#define	SECT_4K_PMC		0x10	/* SPINOR_OP_BE_4K_PMC works uniformly */
+-#define	SPI_NOR_DUAL_READ	0x20    /* Flash supports Dual Read */
+-#define	SPI_NOR_QUAD_READ	0x40    /* Flash supports Quad Read */
+-#define	USE_FSR			0x80	/* use flag status register */
+-};
+-
++/* Used when the "_ext_id" is two bytes at most */
+ #define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags)	\
+ 	((kernel_ulong_t)&(struct flash_info) {				\
+-		.jedec_id = (_jedec_id),				\
+-		.ext_id = (_ext_id),					\
++		.id = {							\
++			((_jedec_id) >> 16) & 0xff,			\
++			((_jedec_id) >> 8) & 0xff,			\
++			(_jedec_id) & 0xff,				\
++			((_ext_id) >> 8) & 0xff,			\
++			(_ext_id) & 0xff,				\
++			},						\
++		.id_len = (!(_jedec_id) ? 0 : (3 + ((_ext_id) ? 2 : 0))),	\
++		.sector_size = (_sector_size),				\
++		.n_sectors = (_n_sectors),				\
++		.page_size = 256,					\
++		.flags = (_flags),					\
++	})
++
++#define INFO6(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags)	\
++	((kernel_ulong_t)&(struct flash_info) {				\
++		.id = {							\
++			((_jedec_id) >> 16) & 0xff,			\
++			((_jedec_id) >> 8) & 0xff,			\
++			(_jedec_id) & 0xff,				\
++			((_ext_id) >> 16) & 0xff,			\
++			((_ext_id) >> 8) & 0xff,			\
++			(_ext_id) & 0xff,				\
++			},						\
++		.id_len = 6,						\
+ 		.sector_size = (_sector_size),				\
+ 		.n_sectors = (_n_sectors),				\
+ 		.page_size = 256,					\
+@@ -507,6 +532,9 @@ static const struct spi_device_id spi_no
+ 	{ "mr25h256", CAT25_INFO( 32 * 1024, 1, 256, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
+ 	{ "mr25h10",  CAT25_INFO(128 * 1024, 1, 256, 3, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
+ 
++	/* Fujitsu */
++	{ "mb85rs1mt", INFO(0x047f27, 0, 128 * 1024, 1, SPI_NOR_NO_ERASE) },
++
+ 	/* GigaDevice */
+ 	{ "gd25q32", INFO(0xc84016, 0, 64 * 1024,  64, SECT_4K) },
+ 	{ "gd25q64", INFO(0xc84017, 0, 64 * 1024, 128, SECT_4K) },
+@@ -532,6 +560,7 @@ static const struct spi_device_id spi_no
+ 	{ "mx66l1g55g",  INFO(0xc2261b, 0, 64 * 1024, 2048, SPI_NOR_QUAD_READ) },
+ 
+ 	/* Micron */
++	{ "n25q032",	 INFO(0x20ba16, 0, 64 * 1024,   64, 0) },
+ 	{ "n25q064",     INFO(0x20ba17, 0, 64 * 1024,  128, 0) },
+ 	{ "n25q128a11",  INFO(0x20bb18, 0, 64 * 1024,  256, 0) },
+ 	{ "n25q128a13",  INFO(0x20ba18, 0, 64 * 1024,  256, 0) },
+@@ -556,6 +585,7 @@ static const struct spi_device_id spi_no
+ 	{ "s70fl01gs",  INFO(0x010221, 0x4d00, 256 * 1024, 256, 0) },
+ 	{ "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024,  64, 0) },
+ 	{ "s25sl12801", INFO(0x012018, 0x0301,  64 * 1024, 256, 0) },
++	{ "s25fl128s",	INFO6(0x012018, 0x4d0180, 64 * 1024, 256, SPI_NOR_QUAD_READ) },
+ 	{ "s25fl129p0", INFO(0x012018, 0x4d00, 256 * 1024,  64, 0) },
+ 	{ "s25fl129p1", INFO(0x012018, 0x4d01,  64 * 1024, 256, 0) },
+ 	{ "s25sl004a",  INFO(0x010212,      0,  64 * 1024,   8, 0) },
+@@ -577,6 +607,7 @@ static const struct spi_device_id spi_no
+ 	{ "sst25wf010",  INFO(0xbf2502, 0, 64 * 1024,  2, SECT_4K | SST_WRITE) },
+ 	{ "sst25wf020",  INFO(0xbf2503, 0, 64 * 1024,  4, SECT_4K | SST_WRITE) },
+ 	{ "sst25wf040",  INFO(0xbf2504, 0, 64 * 1024,  8, SECT_4K | SST_WRITE) },
++	{ "sst25wf080",  INFO(0xbf2505, 0, 64 * 1024, 16, SECT_4K | SST_WRITE) },
+ 
+ 	/* ST Microelectronics -- newer production may have feature updates */
+ 	{ "m25p05",  INFO(0x202010,  0,  32 * 1024,   2, 0) },
+@@ -588,7 +619,6 @@ static const struct spi_device_id spi_no
+ 	{ "m25p32",  INFO(0x202016,  0,  64 * 1024,  64, 0) },
+ 	{ "m25p64",  INFO(0x202017,  0,  64 * 1024, 128, 0) },
+ 	{ "m25p128", INFO(0x202018,  0, 256 * 1024,  64, 0) },
+-	{ "n25q032", INFO(0x20ba16,  0,  64 * 1024,  64, 0) },
+ 
+ 	{ "m25p05-nonjedec",  INFO(0, 0,  32 * 1024,   2, 0) },
+ 	{ "m25p10-nonjedec",  INFO(0, 0,  32 * 1024,   4, 0) },
+@@ -644,32 +674,24 @@ static const struct spi_device_id spi_no
+ static const struct spi_device_id *spi_nor_read_id(struct spi_nor *nor)
+ {
+ 	int			tmp;
+-	u8			id[5];
+-	u32			jedec;
+-	u16                     ext_jedec;
++	u8			id[SPI_NOR_MAX_ID_LEN];
+ 	struct flash_info	*info;
+ 
+-	tmp = nor->read_reg(nor, SPINOR_OP_RDID, id, 5);
++	tmp = nor->read_reg(nor, SPINOR_OP_RDID, id, SPI_NOR_MAX_ID_LEN);
+ 	if (tmp < 0) {
+ 		dev_dbg(nor->dev, " error %d reading JEDEC ID\n", tmp);
+ 		return ERR_PTR(tmp);
+ 	}
+-	jedec = id[0];
+-	jedec = jedec << 8;
+-	jedec |= id[1];
+-	jedec = jedec << 8;
+-	jedec |= id[2];
+-
+-	ext_jedec = id[3] << 8 | id[4];
+ 
+ 	for (tmp = 0; tmp < ARRAY_SIZE(spi_nor_ids) - 1; tmp++) {
+ 		info = (void *)spi_nor_ids[tmp].driver_data;
+-		if (info->jedec_id == jedec) {
+-			if (info->ext_id == 0 || info->ext_id == ext_jedec)
++		if (info->id_len) {
++			if (!memcmp(info->id, id, info->id_len))
+ 				return &spi_nor_ids[tmp];
+ 		}
+ 	}
+-	dev_err(nor->dev, "unrecognized JEDEC id %06x\n", jedec);
++	dev_err(nor->dev, "unrecognized JEDEC id bytes: %02x, %2x, %2x\n",
++		id[0], id[1], id[2]);
+ 	return ERR_PTR(-ENODEV);
+ }
+ 
+@@ -704,11 +726,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;
+@@ -720,7 +737,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;
+ 	}
+@@ -732,7 +749,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;
+@@ -741,7 +758,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;
+ 
+@@ -752,7 +769,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);
+@@ -780,11 +797,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);
+@@ -803,16 +815,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)
+@@ -825,7 +841,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);
+@@ -875,11 +891,11 @@ static int spansion_quad_enable(struct s
+ 	return 0;
+ }
+ 
+-static int set_quad_mode(struct spi_nor *nor, u32 jedec_id)
++static int set_quad_mode(struct spi_nor *nor, struct flash_info *info)
+ {
+ 	int status;
+ 
+-	switch (JEDEC_MFR(jedec_id)) {
++	switch (JEDEC_MFR(info)) {
+ 	case CFI_MFR_MACRONIX:
+ 		status = macronix_quad_enable(nor);
+ 		if (status) {
+@@ -905,11 +921,6 @@ static int spi_nor_check(struct spi_nor
+ 		return -EINVAL;
+ 	}
+ 
+-	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;
+ }
+ 
+@@ -927,16 +938,24 @@ int spi_nor_scan(struct spi_nor *nor, co
+ 	if (ret)
+ 		return ret;
+ 
+-	id = spi_nor_match_id(name);
+-	if (!id)
++	/* Try to auto-detect if chip name wasn't specified */
++	if (!name)
++		id = spi_nor_read_id(nor);
++	else
++		id = spi_nor_match_id(name);
++	if (IS_ERR_OR_NULL(id))
+ 		return -ENOENT;
+ 
+ 	info = (void *)id->driver_data;
+ 
+-	if (info->jedec_id) {
++	/*
++	 * If caller has specified name of flash model that can normally be
++	 * detected using JEDEC, let's verify it.
++	 */
++	if (name && info->id_len) {
+ 		const struct spi_device_id *jid;
+ 
+-		jid = nor->read_id(nor);
++		jid = spi_nor_read_id(nor);
+ 		if (IS_ERR(jid)) {
+ 			return PTR_ERR(jid);
+ 		} else if (jid != id) {
+@@ -961,9 +980,9 @@ int spi_nor_scan(struct spi_nor *nor, co
+ 	 * up with the software protection bits set
+ 	 */
+ 
+-	if (JEDEC_MFR(info->jedec_id) == CFI_MFR_ATMEL ||
+-	    JEDEC_MFR(info->jedec_id) == CFI_MFR_INTEL ||
+-	    JEDEC_MFR(info->jedec_id) == CFI_MFR_SST) {
++	if (JEDEC_MFR(info) == CFI_MFR_ATMEL ||
++	    JEDEC_MFR(info) == CFI_MFR_INTEL ||
++	    JEDEC_MFR(info) == CFI_MFR_SST) {
+ 		write_enable(nor);
+ 		write_sr(nor, 0);
+ 	}
+@@ -978,7 +997,7 @@ int spi_nor_scan(struct spi_nor *nor, co
+ 	mtd->_read = spi_nor_read;
+ 
+ 	/* nor protection support for STmicro chips */
+-	if (JEDEC_MFR(info->jedec_id) == CFI_MFR_ST) {
++	if (JEDEC_MFR(info) == CFI_MFR_ST) {
+ 		mtd->_lock = spi_nor_lock;
+ 		mtd->_unlock = spi_nor_unlock;
+ 	}
+@@ -989,9 +1008,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 */
+@@ -1032,7 +1050,7 @@ int spi_nor_scan(struct spi_nor *nor, co
+ 
+ 	/* Quad/Dual-read mode takes precedence over fast/normal */
+ 	if (mode == SPI_NOR_QUAD && info->flags & SPI_NOR_QUAD_READ) {
+-		ret = set_quad_mode(nor, info->jedec_id);
++		ret = set_quad_mode(nor, info);
+ 		if (ret) {
+ 			dev_err(dev, "quad mode not supported\n");
+ 			return ret;
+@@ -1068,7 +1086,7 @@ int spi_nor_scan(struct spi_nor *nor, co
+ 	else if (mtd->size > 0x1000000) {
+ 		/* enable 4-byte addressing if the device exceeds 16MiB */
+ 		nor->addr_width = 4;
+-		if (JEDEC_MFR(info->jedec_id) == CFI_MFR_AMD) {
++		if (JEDEC_MFR(info) == CFI_MFR_AMD) {
+ 			/* Dedicated 4-byte command set */
+ 			switch (nor->flash_read) {
+ 			case SPI_NOR_QUAD:
+@@ -1089,7 +1107,7 @@ int spi_nor_scan(struct spi_nor *nor, co
+ 			nor->erase_opcode = SPINOR_OP_SE_4B;
+ 			mtd->erasesize = info->sector_size;
+ 		} else
+-			set_4byte(nor, info->jedec_id, 1);
++			set_4byte(nor, info, 1);
+ 	} else {
+ 		nor->addr_width = 3;
+ 	}
+--- 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
+@@ -139,9 +144,6 @@ enum spi_nor_ops {
+  * @write_xfer:		[OPTIONAL] the writefundamental primitive
+  * @read_reg:		[DRIVER-SPECIFIC] read out the register
+  * @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 +162,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];
+ 
+@@ -172,8 +175,6 @@ struct spi_nor {
+ 	int (*read_reg)(struct spi_nor *nor, u8 opcode, u8 *buf, int len);
+ 	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);
diff --git a/target/linux/bcm53xx/patches-3.18/402-mtd-spi-nor-allow-NULL-as-spi_device_id-in-spi_nor_s.patch b/target/linux/bcm53xx/patches-3.18/402-mtd-spi-nor-allow-NULL-as-spi_device_id-in-spi_nor_s.patch
deleted file mode 100644
index b72e2e2613..0000000000
--- a/target/linux/bcm53xx/patches-3.18/402-mtd-spi-nor-allow-NULL-as-spi_device_id-in-spi_nor_s.patch
+++ /dev/null
@@ -1,46 +0,0 @@
---- a/drivers/mtd/spi-nor/spi-nor.c
-+++ b/drivers/mtd/spi-nor/spi-nor.c
-@@ -931,29 +931,23 @@ int spi_nor_scan(struct spi_nor *nor, co
- 	if (!id)
- 		return -ENOENT;
- 
--	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.18/403-mtd-spi-nor-refactor-wait-till-ready.patch b/target/linux/bcm53xx/patches-3.18/403-mtd-spi-nor-refactor-wait-till-ready.patch
deleted file mode 100644
index 08e53a7418..0000000000
--- a/target/linux/bcm53xx/patches-3.18/403-mtd-spi-nor-refactor-wait-till-ready.patch
+++ /dev/null
@@ -1,374 +0,0 @@
---- 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
-@@ -165,81 +165,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);
- }
- 
-@@ -292,6 +280,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)) {
-@@ -299,6 +289,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.
-@@ -314,9 +308,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;
-@@ -341,11 +341,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))
-@@ -388,11 +383,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))
-@@ -704,11 +694,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;
-@@ -720,7 +705,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;
- 	}
-@@ -732,7 +717,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;
-@@ -741,7 +726,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;
- 
-@@ -752,7 +737,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);
-@@ -780,11 +765,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);
-@@ -803,16 +783,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)
-@@ -825,7 +809,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);
-@@ -907,8 +891,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;
- }
-@@ -983,9 +965,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);
diff --git a/target/linux/bcm53xx/patches-3.18/404-mtd-bcm53xxspiflash-new-driver-for-SPI-flahes-on-Bro.patch b/target/linux/bcm53xx/patches-3.18/404-mtd-bcm53xxspiflash-new-driver-for-SPI-flahes-on-Bro.patch
index 80e1d324d7..41ef3b300e 100644
--- a/target/linux/bcm53xx/patches-3.18/404-mtd-bcm53xxspiflash-new-driver-for-SPI-flahes-on-Bro.patch
+++ b/target/linux/bcm53xx/patches-3.18/404-mtd-bcm53xxspiflash-new-driver-for-SPI-flahes-on-Bro.patch
@@ -17,247 +17,3 @@
  obj-$(CONFIG_MTD_SPI_NOR)	+= spi-nor.o
  obj-$(CONFIG_SPI_FSL_QUADSPI)	+= fsl-quadspi.o
 +obj-$(CONFIG_MTD_SPI_BCM53XXSPIFLASH)	+= bcm53xxspiflash.o
---- /dev/null
-+++ b/drivers/mtd/spi-nor/bcm53xxspiflash.c
-@@ -0,0 +1,241 @@
-+#include <linux/module.h>
-+#include <linux/delay.h>
-+#include <linux/spi/spi.h>
-+#include <linux/mtd/spi-nor.h>
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/cfi.h>
-+
-+static const char * const probes[] = { "bcm47xxpart", NULL };
-+
-+struct bcm53xxsf {
-+	struct spi_device *spi;
-+	struct mtd_info mtd;
-+	struct spi_nor nor;
-+};
-+
-+/**************************************************
-+ * spi-nor API
-+ **************************************************/
-+
-+static int bcm53xxspiflash_read_reg(struct spi_nor *nor, u8 opcode, u8 *buf,
-+				   int len)
-+{
-+	struct bcm53xxsf *b53sf = nor->priv;
-+
-+	return spi_write_then_read(b53sf->spi, &opcode, 1, buf, len);
-+}
-+
-+static int bcm53xxspiflash_write_reg(struct spi_nor *nor, u8 opcode, u8 *buf,
-+				     int len, int write_enable)
-+{
-+	struct bcm53xxsf *b53sf = nor->priv;
-+	u8 *cmd = kzalloc(len + 1, GFP_KERNEL);
-+	int err;
-+
-+	if (!cmd)
-+		return -ENOMEM;
-+
-+	cmd[0] = opcode;
-+	memcpy(&cmd[1], buf, len);
-+	err = spi_write(b53sf->spi, cmd, len + 1);
-+
-+	kfree(cmd);
-+
-+	return err;
-+}
-+
-+static int bcm53xxspiflash_read(struct spi_nor *nor, loff_t from, size_t len,
-+				size_t *retlen, u_char *buf)
-+{
-+	struct bcm53xxsf *b53sf = nor->priv;
-+	struct spi_message m;
-+	struct spi_transfer t[2] = { { 0 }, { 0 } };
-+	unsigned char cmd[5];
-+	int cmd_len = 0;
-+	int err;
-+
-+	spi_message_init(&m);
-+
-+	cmd[cmd_len++] = SPINOR_OP_READ;
-+	if (b53sf->mtd.size > 0x1000000)
-+		cmd[cmd_len++] = (from & 0xFF000000) >> 24;
-+	cmd[cmd_len++] = (from & 0x00FF0000) >> 16;
-+	cmd[cmd_len++] = (from & 0x0000FF00) >> 8;
-+	cmd[cmd_len++] = (from & 0x000000FF) >> 0;
-+
-+	t[0].tx_buf = cmd;
-+	t[0].len = cmd_len;
-+	spi_message_add_tail(&t[0], &m);
-+
-+	t[1].rx_buf = buf;
-+	t[1].len = len;
-+	spi_message_add_tail(&t[1], &m);
-+
-+	err = spi_sync(b53sf->spi, &m);
-+	if (err)
-+		return err;
-+
-+	if (retlen && m.actual_length > cmd_len)
-+		*retlen = m.actual_length - cmd_len;
-+
-+	return 0;
-+}
-+
-+static void bcm53xxspiflash_write(struct spi_nor *nor, loff_t to, size_t len,
-+				  size_t *retlen, const u_char *buf)
-+{
-+	struct bcm53xxsf *b53sf = nor->priv;
-+	struct spi_message m;
-+	struct spi_transfer t = { 0 };
-+	u8 *cmd = kzalloc(len + 5, GFP_KERNEL);
-+	int cmd_len = 0;
-+	int err;
-+
-+	if (!cmd)
-+		return;
-+
-+	spi_message_init(&m);
-+
-+	cmd[cmd_len++] = nor->program_opcode;
-+	if (b53sf->mtd.size > 0x1000000)
-+		cmd[cmd_len++] = (to & 0xFF000000) >> 24;
-+	cmd[cmd_len++] = (to & 0x00FF0000) >> 16;
-+	cmd[cmd_len++] = (to & 0x0000FF00) >> 8;
-+	cmd[cmd_len++] = (to & 0x000000FF) >> 0;
-+	memcpy(&cmd[cmd_len], buf, len);
-+
-+	t.tx_buf = cmd;
-+	t.len = cmd_len + len;
-+	spi_message_add_tail(&t, &m);
-+
-+	err = spi_sync(b53sf->spi, &m);
-+	if (err)
-+		goto out;
-+
-+	if (retlen && m.actual_length > cmd_len)
-+		*retlen += m.actual_length - cmd_len;
-+
-+out:
-+	kfree(cmd);
-+}
-+
-+static int bcm53xxspiflash_erase(struct spi_nor *nor, loff_t offs)
-+{
-+	struct bcm53xxsf *b53sf = nor->priv;
-+	unsigned char cmd[5];
-+	int i;
-+
-+	i = 0;
-+	cmd[i++] = nor->erase_opcode;
-+	if (b53sf->mtd.size > 0x1000000)
-+		cmd[i++] = (offs & 0xFF000000) >> 24;
-+	cmd[i++] = ((offs & 0x00FF0000) >> 16);
-+	cmd[i++] = ((offs & 0x0000FF00) >> 8);
-+	cmd[i++] = ((offs & 0x000000FF) >> 0);
-+
-+	return spi_write(b53sf->spi, cmd, i);
-+}
-+
-+static const struct spi_device_id *bcm53xxspiflash_read_id(struct spi_nor *nor)
-+{
-+	struct bcm53xxsf *b53sf = nor->priv;
-+	struct device *dev = &b53sf->spi->dev;
-+	const struct spi_device_id *id;
-+	unsigned char cmd[4];
-+	unsigned char resp[2];
-+	char *name = NULL;
-+	int err;
-+
-+	/* SST and Winbond/NexFlash specific command */
-+	cmd[0] = 0x90; /* Read Manufacturer / Device ID */
-+	cmd[1] = 0;
-+	cmd[2] = 0;
-+	cmd[3] = 0;
-+	err = spi_write_then_read(b53sf->spi, cmd, 4, resp, 2);
-+	if (err < 0) {
-+		dev_err(dev, "error reading SPI flash id\n");
-+		return ERR_PTR(-EBUSY);
-+	}
-+	switch (resp[0]) {
-+	case 0xef: /* Winbond/NexFlash */
-+		switch (resp[1]) {
-+		case 0x17:
-+			name = "w25q128";
-+			break;
-+		}
-+		if (!name) {
-+			dev_err(dev, "Unknown Winbond/NexFlash flash: %02X %02X\n",
-+				resp[0], resp[1]);
-+			return ERR_PTR(-ENOTSUPP);
-+		}
-+		goto found_name;
-+	}
-+
-+	/* TODO: Try more ID commands */
-+
-+	return ERR_PTR(-ENODEV);
-+
-+found_name:
-+//	id = spi_nor_match_id(name);
-+//	if (!id) {
-+//		dev_err(dev, "No matching entry for %s flash\n", name);
-+//		return ERR_PTR(-ENOENT);
-+//	}
-+
-+	return id;
-+}
-+
-+/**************************************************
-+ * SPI driver
-+ **************************************************/
-+
-+static int bcm53xxspiflash_probe(struct spi_device *spi)
-+{
-+	struct bcm53xxsf *b53sf;
-+	int err;
-+
-+	b53sf = devm_kzalloc(&spi->dev, sizeof(*b53sf), GFP_KERNEL);
-+	if (!b53sf)
-+		return -ENOMEM;
-+	spi_set_drvdata(spi, b53sf);
-+
-+	b53sf->spi = spi;
-+
-+	b53sf->mtd.priv = &b53sf->nor;
-+
-+	b53sf->nor.mtd = &b53sf->mtd;
-+	b53sf->nor.dev = &spi->dev;
-+	b53sf->nor.read_reg = bcm53xxspiflash_read_reg;
-+	b53sf->nor.write_reg = bcm53xxspiflash_write_reg;
-+	b53sf->nor.read = bcm53xxspiflash_read;
-+	b53sf->nor.write = bcm53xxspiflash_write;
-+	b53sf->nor.erase = bcm53xxspiflash_erase;
-+	b53sf->nor.read_id = bcm53xxspiflash_read_id;
-+	b53sf->nor.priv = b53sf;
-+
-+	err = spi_nor_scan(&b53sf->nor, "w25q128", SPI_NOR_NORMAL);
-+	if (err)
-+		return err;
-+
-+	err = mtd_device_parse_register(&b53sf->mtd, probes, NULL, NULL, 0);
-+	if (err)
-+		return err;
-+
-+	return 0;
-+}
-+
-+static int bcm53xxspiflash_remove(struct spi_device *spi)
-+{
-+	return 0;
-+}
-+
-+static struct spi_driver bcm53xxspiflash_driver = {
-+	.driver = {
-+		.name	= "bcm53xxspiflash",
-+		.owner	= THIS_MODULE,
-+	},
-+	.probe		= bcm53xxspiflash_probe,
-+	.remove		= bcm53xxspiflash_remove,
-+};
-+
-+module_spi_driver(bcm53xxspiflash_driver);
diff --git a/target/linux/bcm53xx/patches-3.18/405-mtd-bcm53xxspiflash-try-using-JEDEC-as-one-of-method.patch b/target/linux/bcm53xx/patches-3.18/405-mtd-bcm53xxspiflash-try-using-JEDEC-as-one-of-method.patch
deleted file mode 100644
index d97441f586..0000000000
--- a/target/linux/bcm53xx/patches-3.18/405-mtd-bcm53xxspiflash-try-using-JEDEC-as-one-of-method.patch
+++ /dev/null
@@ -1,42 +0,0 @@
---- a/drivers/mtd/spi-nor/bcm53xxspiflash.c
-+++ b/drivers/mtd/spi-nor/bcm53xxspiflash.c
-@@ -173,7 +173,8 @@ static const struct spi_device_id *bcm53
- 
- 	/* TODO: Try more ID commands */
- 
--	return ERR_PTR(-ENODEV);
-+	/* Some chips used by Broadcom may actually support JEDEC */
-+	return spi_nor_read_id(nor);
- 
- found_name:
- //	id = spi_nor_match_id(name);
---- a/drivers/mtd/spi-nor/spi-nor.c
-+++ b/drivers/mtd/spi-nor/spi-nor.c
-@@ -631,7 +631,7 @@ static const struct spi_device_id spi_no
- 	{ },
- };
- 
--static const struct spi_device_id *spi_nor_read_id(struct spi_nor *nor)
-+const struct spi_device_id *spi_nor_read_id(struct spi_nor *nor)
- {
- 	int			tmp;
- 	u8			id[5];
-@@ -662,6 +662,7 @@ static const struct spi_device_id *spi_n
- 	dev_err(nor->dev, "unrecognized JEDEC id %06x\n", jedec);
- 	return ERR_PTR(-ENODEV);
- }
-+EXPORT_SYMBOL_GPL(spi_nor_read_id);
- 
- static int spi_nor_read(struct mtd_info *mtd, loff_t from, size_t len,
- 			size_t *retlen, u_char *buf)
---- a/include/linux/mtd/spi-nor.h
-+++ b/include/linux/mtd/spi-nor.h
-@@ -188,6 +188,8 @@ struct spi_nor {
- 	void *priv;
- };
- 
-+const struct spi_device_id *spi_nor_read_id(struct spi_nor *nor);
-+
- /**
-  * spi_nor_scan() - scan the SPI NOR
-  * @nor:	the spi_nor structure