--- /dev/null
+--- a/drivers/mtd/bcm47xxpart.c
++++ b/drivers/mtd/bcm47xxpart.c
+@@ -19,6 +19,12 @@
+ /* 10 parts were found on sflash on Netgear WNDR4500 */
+ #define BCM47XXPART_MAX_PARTS 12
+
++/*
++ * Amount of bytes we read when analyzing each block of flash memory.
++ * Set it big enough to allow detecting partition and reading important data.
++ */
++#define BCM47XXPART_BYTES_TO_READ 0x404
++
+ /* Magics */
+ #define BOARD_DATA_MAGIC 0x5246504D /* MPFR */
+ #define POT_MAGIC1 0x54544f50 /* POTT */
+@@ -57,17 +63,14 @@ static int bcm47xxpart_parse(struct mtd_
+ struct trx_header *trx;
+ int trx_part = -1;
+ int last_trx_part = -1;
+- int max_bytes_to_read = 0x8004;
+
+ if (blocksize <= 0x10000)
+ blocksize = 0x10000;
+- if (blocksize == 0x20000)
+- max_bytes_to_read = 0x18004;
+
+ /* Alloc */
+ parts = kzalloc(sizeof(struct mtd_partition) * BCM47XXPART_MAX_PARTS,
+ GFP_KERNEL);
+- buf = kzalloc(max_bytes_to_read, GFP_KERNEL);
++ buf = kzalloc(BCM47XXPART_BYTES_TO_READ, GFP_KERNEL);
+
+ /* Parse block by block looking for magics */
+ for (offset = 0; offset <= master->size - blocksize;
+@@ -82,7 +85,7 @@ static int bcm47xxpart_parse(struct mtd_
+ }
+
+ /* Read beginning of the block */
+- if (mtd_read(master, offset, max_bytes_to_read,
++ if (mtd_read(master, offset, BCM47XXPART_BYTES_TO_READ,
+ &bytes_read, (uint8_t *)buf) < 0) {
+ pr_err("mtd_read error while parsing (offset: 0x%X)!\n",
+ offset);
+@@ -97,16 +100,9 @@ static int bcm47xxpart_parse(struct mtd_
+ }
+
+ /* Standard NVRAM */
+- if (buf[0x000 / 4] == NVRAM_HEADER ||
+- buf[0x1000 / 4] == NVRAM_HEADER ||
+- buf[0x8000 / 4] == NVRAM_HEADER ||
+- (blocksize == 0x20000 && (
+- buf[0x10000 / 4] == NVRAM_HEADER ||
+- buf[0x11000 / 4] == NVRAM_HEADER ||
+- buf[0x18000 / 4] == NVRAM_HEADER))) {
++ if (buf[0x000 / 4] == NVRAM_HEADER) {
+ bcm47xxpart_add_part(&parts[curr_part++], "nvram",
+ offset, 0);
+- offset = rounddown(offset, blocksize);
+ continue;
+ }
+
+++ /dev/null
---- a/drivers/mtd/bcm47xxpart.c
-+++ b/drivers/mtd/bcm47xxpart.c
-@@ -58,6 +58,7 @@ static int bcm47xxpart_parse(struct mtd_
- int trx_part = -1;
- int last_trx_part = -1;
- int max_bytes_to_read = 0x8004;
-+ bool found_nvram = false;
-
- if (blocksize <= 0x10000)
- blocksize = 0x10000;
-@@ -107,6 +108,7 @@ static int bcm47xxpart_parse(struct mtd_
- bcm47xxpart_add_part(&parts[curr_part++], "nvram",
- offset, 0);
- offset = rounddown(offset, blocksize);
-+ found_nvram = true;
- continue;
- }
-
-@@ -194,6 +196,15 @@ static int bcm47xxpart_parse(struct mtd_
- parts[trx_part].offset;
- }
-
-+ if (!found_nvram) {
-+ pr_err("can not find a nvram partition reserve last block\n");
-+ bcm47xxpart_add_part(&parts[curr_part++], "nvram_guess",
-+ master->size - blocksize, MTD_WRITEABLE);
-+ for (i = 0; i < curr_part; i++) {
-+ if (parts[i].size + parts[i].offset == master->size)
-+ parts[i].offset -= blocksize;
-+ }
-+ }
- *pparts = parts;
- return curr_part;
- };
--- /dev/null
+--- a/drivers/mtd/bcm47xxpart.c
++++ b/drivers/mtd/bcm47xxpart.c
+@@ -63,6 +63,7 @@ static int bcm47xxpart_parse(struct mtd_
+ struct trx_header *trx;
+ int trx_part = -1;
+ int last_trx_part = -1;
++ int possible_nvram_sizes[] = { 0x8000, 0xF000, 0x10000, };
+
+ if (blocksize <= 0x10000)
+ blocksize = 0x10000;
+@@ -99,13 +100,6 @@ static int bcm47xxpart_parse(struct mtd_
+ continue;
+ }
+
+- /* Standard NVRAM */
+- if (buf[0x000 / 4] == NVRAM_HEADER) {
+- bcm47xxpart_add_part(&parts[curr_part++], "nvram",
+- offset, 0);
+- continue;
+- }
+-
+ /*
+ * board_data starts with board_id which differs across boards,
+ * but we can use 'MPFR' (hopefully) magic at 0x100
+@@ -174,6 +168,30 @@ static int bcm47xxpart_parse(struct mtd_
+ continue;
+ }
+ }
++
++ /* Look for NVRAM at the end of the last block. */
++ for (i = 0; i < ARRAY_SIZE(possible_nvram_sizes); i++) {
++ if (curr_part > BCM47XXPART_MAX_PARTS) {
++ pr_warn("Reached maximum number of partitions, scanning stopped!\n");
++ break;
++ }
++
++ offset = master->size - possible_nvram_sizes[i];
++ if (mtd_read(master, offset, 0x4, &bytes_read,
++ (uint8_t *)buf) < 0) {
++ pr_err("mtd_read error while reading at offset 0x%X!\n",
++ offset);
++ continue;
++ }
++
++ /* Standard NVRAM */
++ if (buf[0] == NVRAM_HEADER) {
++ bcm47xxpart_add_part(&parts[curr_part++], "nvram",
++ master->size - blocksize, 0);
++ break;
++ }
++ }
++
+ kfree(buf);
+
+ /*
--- /dev/null
+--- a/drivers/mtd/bcm47xxpart.c
++++ b/drivers/mtd/bcm47xxpart.c
+@@ -23,9 +23,10 @@
+ * Amount of bytes we read when analyzing each block of flash memory.
+ * Set it big enough to allow detecting partition and reading important data.
+ */
+-#define BCM47XXPART_BYTES_TO_READ 0x404
++#define BCM47XXPART_BYTES_TO_READ 0x4e8
+
+ /* Magics */
++#define CFE_MAGIC 0x43464531 /* 1EFC */
+ #define BOARD_DATA_MAGIC 0x5246504D /* MPFR */
+ #define POT_MAGIC1 0x54544f50 /* POTT */
+ #define POT_MAGIC2 0x504f /* OP */
+@@ -93,8 +94,9 @@ static int bcm47xxpart_parse(struct mtd_
+ continue;
+ }
+
+- /* CFE has small NVRAM at 0x400 */
+- if (buf[0x400 / 4] == NVRAM_HEADER) {
++ /* Magic or small NVRAM at 0x400 */
++ if (buf[0x4e0 / 4] == CFE_MAGIC ||
++ buf[0x400 / 4] == NVRAM_HEADER) {
+ bcm47xxpart_add_part(&parts[curr_part++], "boot",
+ offset, MTD_WRITEABLE);
+ continue;
--- /dev/null
+--- a/drivers/mtd/bcm47xxpart.c
++++ b/drivers/mtd/bcm47xxpart.c
+@@ -65,6 +65,7 @@ static int bcm47xxpart_parse(struct mtd_
+ int trx_part = -1;
+ int last_trx_part = -1;
+ int possible_nvram_sizes[] = { 0x8000, 0xF000, 0x10000, };
++ bool found_nvram = false;
+
+ if (blocksize <= 0x10000)
+ blocksize = 0x10000;
+@@ -190,12 +191,23 @@ static int bcm47xxpart_parse(struct mtd_
+ if (buf[0] == NVRAM_HEADER) {
+ bcm47xxpart_add_part(&parts[curr_part++], "nvram",
+ master->size - blocksize, 0);
++ found_nvram = true;
+ break;
+ }
+ }
+
+ kfree(buf);
+
++ if (!found_nvram) {
++ pr_err("can not find a nvram partition reserve last block\n");
++ bcm47xxpart_add_part(&parts[curr_part++], "nvram_guess",
++ master->size - blocksize * 2, MTD_WRITEABLE);
++ for (i = 0; i < curr_part; i++) {
++ if (parts[i].size + parts[i].offset == master->size)
++ parts[i].offset -= blocksize * 2;
++ }
++ }
++
+ /*
+ * Assume that partitions end at the beginning of the one they are
+ * followed by.