[PATCH]: 2.6.14-rc5 arch-ixp4xx/system.h: ensure flash is readable before reboot

From: John Bowler
Date: Tue Oct 25 2005 - 13:13:38 EST


This patch was discussed before on l-a-k under the subject "ixp4xx flash:
don't twiddle chip selects?" (that thread starts with discussion of a
*different* patch, this is related, at least stylistically.) The prior
discussion examined other possible places to do this patch (including within
the MTD driver).

The problem is that a machine reboot hangs because the attempt to read the
flash (the very first instruction fetch after the reset) fails as a result
of the flash being in a non-read (command) mode.

The problem is ARCH specific, I suspect it actually happens on any IXP4XX
system which has onboard flash which is used for a JFFS2 file system and
which does not have a hardware reset on the flash (I am told this applies to
any XScale because the reset line simply doesn't come out of the CPU chip.)
I can only confirm the problem on the NSLU2, it is intermittent (sometimes
very hard to reproduce). I and other NSLU2/OpenSlug users have been running
with this patch in both LE and BE systems for maybe a month now and have not
seen the hang - so I'm confident of the fix.

The fix is to execute a flash reset command immediately before the reset,
the instruction fetch then works (fetches the instruction at address 0, as
opposed to the results of a flash command.) The command address (0xAA) is
actually irrelevant - any address works just so long as the write ends up
going to the flash chip - hence the fix works for any endianness and any
flash layout. It has been tested on LE builds where the address gets
changed to 0xA8 in the hardware.

Signed-off-by: John Bowler <jbowler@xxxxxxx>

---
linux-2.6.13/.pc/25-nslu2-arch-reset.patch/include/asm-arm/arch-ixp4xx/syste
m.h 2005-08-28 16:41:01.000000000 -0700
+++ linux-2.6.13/include/asm-arm/arch-ixp4xx/system.h 2005-09-25
23:34:14.762872391 -0700
@@ -10,6 +10,7 @@
*/

#include <asm/hardware.h>
+#include <asm/mach-types.h>

static inline void arch_idle(void)
{
@@ -22,6 +23,21 @@

static inline void arch_reset(char mode)
{
+ /* On NSLU2 machines the flash is sometimes left in a non-read
+ * mode, such that attempting a read will cause problems - such as
+ * a hang. This will prevent both hard and soft reboot since the
+ * first thing done is to read the first instruction from the flash!
+ * Therefore issue a flash reset command here.
+ */
+ if ( machine_is_nslu2()) {
+ /* Use the physical address here and write the reset command
+ * to the command address (not technically necessary). See
+ * <linux/mtd/cfi.h> for how to calculate this for other
+ * systems. The NSLU2 has one bank of 16 bit flash.
+ */
+ *(__u16*)(NSLU2_FLASH_BASE+0xAA/*command*/) = 0x00ff/*reset*/;
+ }
+
if ( 1 && mode == 's') {
/* Jump into ROM at address 0 */
cpu_reset(0);
@@ -39,4 +55,3 @@
*IXP4XX_OSWE = IXP4XX_WDT_RESET_ENABLE | IXP4XX_WDT_COUNT_ENABLE;
}
}
-

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/