diff --git a/target/linux/generic/pending-5.4/481-mtd-spi-nor-rework-broken-flash-reset-support.patch b/target/linux/generic/pending-5.4/481-mtd-spi-nor-rework-broken-flash-reset-support.patch
new file mode 100644
index 0000000000000000000000000000000000000000..b2f73a5cbd7dc70dee9756be7705fe4e103cbd78
--- /dev/null
+++ b/target/linux/generic/pending-5.4/481-mtd-spi-nor-rework-broken-flash-reset-support.patch
@@ -0,0 +1,167 @@
+From ea92cbb50a78404e29de2cc3999a240615ffb1c8 Mon Sep 17 00:00:00 2001
+From: Chuanhong Guo <gch981213@gmail.com>
+Date: Mon, 6 Apr 2020 17:58:48 +0800
+Subject: [PATCH] mtd: spi-nor: rework broken-flash-reset support
+
+Instead of resetting flash to 3B address on remove hook, this
+implementation only enters 4B mode when needed, which prevents
+more unexpected reboot stuck. This implementation makes it only
+break when a kernel panic happens during flash operation on 16M+
+areas.
+*OpenWrt only*: silent broken-flash-reset warning. We are not dealing
+with vendors and it's unpleasant for users to se that unnecessary
+and long WARN_ON print.
+
+Signed-off-by: Chuanhong Guo <gch981213@gmail.com>
+---
+ drivers/mtd/spi-nor/spi-nor.c | 52 +++++++++++++++++++++++++++++++++--
+ 1 file changed, 49 insertions(+), 3 deletions(-)
+
+--- a/drivers/mtd/spi-nor/spi-nor.c
++++ b/drivers/mtd/spi-nor/spi-nor.c
+@@ -616,6 +616,22 @@ static void spi_nor_set_4byte_opcodes(st
+ 	}
+ }
+ 
++static int spi_nor_check_set_addr_width(struct spi_nor *nor, loff_t addr)
++{
++	u8 addr_width;
++
++	if ((nor->flags & (SNOR_F_4B_OPCODES | SNOR_F_BROKEN_RESET)) !=
++	    SNOR_F_BROKEN_RESET)
++		return 0;
++
++	addr_width = addr & 0xff000000 ? 4 : 3;
++	if (nor->addr_width == addr_width)
++		return 0;
++
++	nor->addr_width = addr_width;
++	return nor->params.set_4byte(nor, addr_width == 4);
++}
++
+ static int macronix_set_4byte(struct spi_nor *nor, bool enable)
+ {
+ 	if (nor->spimem) {
+@@ -1259,6 +1275,10 @@ static int spi_nor_erase(struct mtd_info
+ 	if (ret)
+ 		return ret;
+ 
++	ret = spi_nor_check_set_addr_width(nor, instr->addr + instr->len);
++	if (ret < 0)
++		return ret;
++
+ 	/* whole-chip erase? */
+ 	if (len == mtd->size && !(nor->flags & SNOR_F_NO_OP_CHIP_ERASE)) {
+ 		unsigned long timeout;
+@@ -1315,6 +1335,7 @@ static int spi_nor_erase(struct mtd_info
+ 	write_disable(nor);
+ 
+ erase_err:
++	spi_nor_check_set_addr_width(nor, 0);
+ 	spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_ERASE);
+ 
+ 	return ret;
+@@ -1621,7 +1642,9 @@ static int spi_nor_lock(struct mtd_info
+ 	if (ret)
+ 		return ret;
+ 
++	spi_nor_check_set_addr_width(nor, ofs + len);
+ 	ret = nor->params.locking_ops->lock(nor, ofs, len);
++	spi_nor_check_set_addr_width(nor, 0);
+ 
+ 	spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_UNLOCK);
+ 	return ret;
+@@ -1636,7 +1659,9 @@ static int spi_nor_unlock(struct mtd_inf
+ 	if (ret)
+ 		return ret;
+ 
++	spi_nor_check_set_addr_width(nor, ofs + len);
+ 	ret = nor->params.locking_ops->unlock(nor, ofs, len);
++	spi_nor_check_set_addr_width(nor, 0);
+ 
+ 	spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_LOCK);
+ 	return ret;
+@@ -1651,7 +1676,9 @@ static int spi_nor_is_locked(struct mtd_
+ 	if (ret)
+ 		return ret;
+ 
++	spi_nor_check_set_addr_width(nor, ofs + len);
+ 	ret = nor->params.locking_ops->is_locked(nor, ofs, len);
++	spi_nor_check_set_addr_width(nor, 0);
+ 
+ 	spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_LOCK);
+ 	return ret;
+@@ -2557,6 +2584,10 @@ static int spi_nor_read(struct mtd_info
+ 	if (ret)
+ 		return ret;
+ 
++	ret = spi_nor_check_set_addr_width(nor, from + len);
++	if (ret < 0)
++		return ret;
++
+ 	while (len) {
+ 		loff_t addr = from;
+ 
+@@ -2580,6 +2611,7 @@ static int spi_nor_read(struct mtd_info
+ 	ret = 0;
+ 
+ read_err:
++	spi_nor_check_set_addr_width(nor, 0);
+ 	spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_READ);
+ 	return ret;
+ }
+@@ -2597,6 +2629,10 @@ static int sst_write(struct mtd_info *mt
+ 	if (ret)
+ 		return ret;
+ 
++	ret = spi_nor_check_set_addr_width(nor, to + len);
++	if (ret < 0)
++		return ret;
++
+ 	write_enable(nor);
+ 
+ 	nor->sst_write_second = false;
+@@ -2659,6 +2695,7 @@ static int sst_write(struct mtd_info *mt
+ 	}
+ sst_write_err:
+ 	*retlen += actual;
++	spi_nor_check_set_addr_width(nor, 0);
+ 	spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_WRITE);
+ 	return ret;
+ }
+@@ -2681,6 +2718,10 @@ static int spi_nor_write(struct mtd_info
+ 	if (ret)
+ 		return ret;
+ 
++	ret = spi_nor_check_set_addr_width(nor, to + len);
++	if (ret < 0)
++		return ret;
++
+ 	for (i = 0; i < len; ) {
+ 		ssize_t written;
+ 		loff_t addr = to + i;
+@@ -2720,6 +2761,7 @@ static int spi_nor_write(struct mtd_info
+ 	}
+ 
+ write_err:
++	spi_nor_check_set_addr_width(nor, 0);
+ 	spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_WRITE);
+ 	return ret;
+ }
+@@ -4726,9 +4768,13 @@ static int spi_nor_init(struct spi_nor *
+ 		 * reboots (e.g., crashes). Warn the user (or hopefully, system
+ 		 * designer) that this is bad.
+ 		 */
+-		WARN_ONCE(nor->flags & SNOR_F_BROKEN_RESET,
+-			  "enabling reset hack; may not recover from unexpected reboots\n");
+-		nor->params.set_4byte(nor, true);
++		if (nor->flags & SNOR_F_BROKEN_RESET) {
++			dev_warn(nor->dev,
++				"enabling reset hack; may not recover from unexpected reboots\n");
++			nor->addr_width = 3;
++		} else {
++			nor->params.set_4byte(nor, true);
++		}
+ 	}
+ 
+ 	return 0;
diff --git a/target/linux/ramips/patches-5.4/302-spi-nor-add-gd25q512.patch b/target/linux/ramips/patches-5.4/302-spi-nor-add-gd25q512.patch
index 3e229bcc1b0105ee9ae0a5f099948bb7a68aa0cd..52eeb3545b223fb57931f1fd75199a2d067a93b7 100644
--- a/target/linux/ramips/patches-5.4/302-spi-nor-add-gd25q512.patch
+++ b/target/linux/ramips/patches-5.4/302-spi-nor-add-gd25q512.patch
@@ -1,6 +1,6 @@
 --- a/drivers/mtd/spi-nor/spi-nor.c
 +++ b/drivers/mtd/spi-nor/spi-nor.c
-@@ -2238,6 +2238,11 @@ static const struct flash_info spi_nor_i
+@@ -2265,6 +2265,11 @@ static const struct flash_info spi_nor_i
  			SPI_NOR_4B_OPCODES | SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
  			.fixups = &gd25q256_fixups,
  	},