[OpenWrt-Devel] Rebooting boards with > 16M SPI flash (was: Re: help)

Paul Fertser fercerpav at gmail.com
Wed Jul 8 08:00:19 EDT 2015


Hi,

ldy647 <ldy647 at 163.com> writes:
> recently, when we install our wireless router, we found when we run
> the reboot command, the board couldn't restart. We hope you could lend
> us a hand to solve this problem. We'll be quite grateful for what you
> do for us.

Apparently MT7620 can't handle 4 byte addressing mode of the flash
memory on hardware (probably ROM bootloader) level so it needs to be
reset somehow prior to resetting the SoC. Some SoCs have a special
output from the watchdog to reset all the on-board peripherals, it
should be connected to the !RESET pin of the flash as well. And the
kernel should then use the watchdog driver to cause a reboot.

As a workaround when hardware modification is not possible and the
flash IC supports a reset command, you can use a patch like this (in
some cases when the kernel is completely stuck it won't help to reboot
of course, as the watchdog will fire on hardware level automatically,
if configured):

diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index b298466..932f307 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -21,6 +21,7 @@
 #include <linux/module.h>
 #include <linux/device.h>
 #include <linux/interrupt.h>
+#include <linux/reboot.h>
 #include <linux/mutex.h>
 #include <linux/math64.h>
 #include <linux/slab.h>
@@ -61,6 +62,9 @@
 /* Used for Spansion flashes only. */
 #define	OPCODE_BRWR		0x17	/* Bank register write */
 
+#define OPCODE_RESET_ENABLE	0x66
+#define OPCODE_RESET		0x99
+
 /* Status Register bits. */
 #define	SR_WIP			1	/* Write in progress */
 #define	SR_WEL			2	/* Write enable latch */
@@ -907,6 +911,21 @@ static const struct spi_device_id *jedec_probe(struct spi_device *spi)
 	return ERR_PTR(-ENODEV);
 }
 
+static int m25p80_reboot(struct notifier_block *nb, unsigned long val,
+			       void *v)
+{
+	struct mtd_info *mtd;
+
+	mtd = container_of(nb, struct mtd_info, reboot_notifier);
+	struct m25p *flash = mtd_to_m25p(mtd);
+
+	flash->command[0] = OPCODE_RESET_ENABLE;
+	spi_write(flash->spi, flash->command, 1);
+	flash->command[0] = OPCODE_RESET;
+	spi_write(flash->spi, flash->command, 1);
+
+	return NOTIFY_DONE;
+}
 
 /*
  * board specific setup should have ensured the SPI clock used here
@@ -1010,6 +1029,7 @@ static int m25p_probe(struct spi_device *spi)
 	flash->mtd.size = info->sector_size * info->n_sectors;
 	flash->mtd._erase = m25p80_erase;
 	flash->mtd._read = m25p80_read;
+	flash->mtd.reboot_notifier.notifier_call = m25p80_reboot;
 
 	/* flash protection support for STmicro chips */
 	if (JEDEC_MFR(info->jedec_id) == CFI_MFR_ST) {
@@ -1085,6 +1105,7 @@ static int m25p_probe(struct spi_device *spi)
 				flash->mtd.eraseregions[i].numblocks);
 
 
+	register_reboot_notifier(&flash->mtd.reboot_notifier);
 	/* partitions should match sector boundaries; and it may be good to
 	 * use readonly partitions for writeprotected sectors (BP2..BP0).
 	 */
@@ -1099,6 +1120,8 @@ static int m25p_remove(struct spi_device *spi)
 	struct m25p	*flash = dev_get_drvdata(&spi->dev);
 	int		status;
 
+	unregister_reboot_notifier(&flash->mtd.reboot_notifier);
+
 	/* Clean up MTD stuff. */
 	status = mtd_device_unregister(&flash->mtd);
 	if (status == 0) {

-- 
Be free, use free (http://www.gnu.org/philosophy/free-sw.html) software!
mailto:fercerpav at gmail.com
_______________________________________________
openwrt-devel mailing list
openwrt-devel at lists.openwrt.org
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel



More information about the openwrt-devel mailing list