Add wait flags to support board/chip specific delays

The NAND flash on the TQM8548_BE modules requires a short delay after
running the UPM pattern like the MPC8360ERDK board does. The TQM8548_BE
requires a further short delay after writing out a buffer. Normally the
R/B pin should be checked, but it's not connected on the TQM8548_BE.
The corresponding Linux FSL UPM driver uses similar delay points at the
same locations. To manage these extra delays in a more general way, I
introduced the "wait_flags" field allowing the board-specific driver to
specify various types of extra delay.

Signed-off-by: Wolfgang Grandegger <wg@grandegger.com>
Signed-off-by: Scott Wood <scottwood@freescale.com>
diff --git a/board/freescale/mpc8360erdk/nand.c b/board/freescale/mpc8360erdk/nand.c
index aa43350..9ffffb4 100644
--- a/board/freescale/mpc8360erdk/nand.c
+++ b/board/freescale/mpc8360erdk/nand.c
@@ -76,7 +76,7 @@
 	.upm_cmd_offset = 8,
 	.upm_addr_offset = 16,
 	.dev_ready = dev_ready,
-	.wait_pattern = 1,
+	.wait_flags = FSL_UPM_WAIT_RUN_PATTERN,
 	.chip_delay = 50,
 };
 
diff --git a/drivers/mtd/nand/fsl_upm.c b/drivers/mtd/nand/fsl_upm.c
index e7e746b..7cb99cb 100644
--- a/drivers/mtd/nand/fsl_upm.c
+++ b/drivers/mtd/nand/fsl_upm.c
@@ -48,6 +48,20 @@
 	}
 }
 
+static void fun_wait(struct fsl_upm_nand *fun)
+{
+	if (fun->dev_ready) {
+		while (!fun->dev_ready(fun->chip_nr))
+			debug("unexpected busy state\n");
+	} else {
+		/*
+		 * If the R/B pin is not connected, like on the TQM8548,
+		 * a short delay is necessary.
+		 */
+		udelay(1);
+	}
+}
+
 #if CONFIG_SYS_NAND_MAX_CHIPS > 1
 static void fun_select_chip(struct mtd_info *mtd, int chip_nr)
 {
@@ -99,15 +113,13 @@
 	fsl_upm_run_pattern(&fun->upm, fun->width, io_addr, mar);
 
 	/*
-	 * Some boards/chips needs this. At least on MPC8360E-RDK we
-	 * need it. Probably weird chip, because I don't see any need
-	 * for this on MPC8555E + Samsung K9F1G08U0A. Usually here are
-	 * 0-2 unexpected busy states per block read.
+	 * Some boards/chips needs this. At least the MPC8360E-RDK and
+	 * TQM8548 need it. Probably weird chip, because I don't see
+	 * any need for this on MPC8555E + Samsung K9F1G08U0A. Usually
+	 * here are 0-2 unexpected busy states per block read.
 	 */
-	if (fun->wait_pattern) {
-		while (!fun->dev_ready(fun->chip_nr))
-			debug("unexpected busy state\n");
-	}
+	if (fun->wait_flags & FSL_UPM_WAIT_RUN_PATTERN)
+		fun_wait(fun);
 }
 
 static u8 nand_read_byte(struct mtd_info *mtd)
@@ -121,9 +133,16 @@
 {
 	int i;
 	struct nand_chip *chip = mtd->priv;
+	struct fsl_upm_nand *fun = chip->priv;
 
-	for (i = 0; i < len; i++)
+	for (i = 0; i < len; i++) {
 		out_8(chip->IO_ADDR_W, buf[i]);
+		if (fun->wait_flags & FSL_UPM_WAIT_WRITE_BYTE)
+			fun_wait(fun);
+	}
+
+	if (fun->wait_flags & FSL_UPM_WAIT_WRITE_BUFFER)
+		fun_wait(fun);
 }
 
 static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
diff --git a/include/linux/mtd/fsl_upm.h b/include/linux/mtd/fsl_upm.h
index 10f5ddd..5d7156f 100644
--- a/include/linux/mtd/fsl_upm.h
+++ b/include/linux/mtd/fsl_upm.h
@@ -15,6 +15,10 @@
 
 #include <linux/mtd/nand.h>
 
+#define FSL_UPM_WAIT_RUN_PATTERN  0x1
+#define FSL_UPM_WAIT_WRITE_BYTE   0x2
+#define FSL_UPM_WAIT_WRITE_BUFFER 0x4
+
 struct fsl_upm {
 	void __iomem *mdr;
 	void __iomem *mxmr;
@@ -29,7 +33,7 @@
 	int upm_cmd_offset;
 	int upm_addr_offset;
 	int upm_mar_chip_offset;
-	int wait_pattern;
+	int wait_flags;
 	int (*dev_ready)(int chip_nr);
 	int chip_delay;
 	int chip_offset;