[PATCH][NOR] cfi_cmdset_0001.c: Max timeouts for erase and write operations

Anders Grafström grfstrm at users.sourceforge.net
Tue May 6 14:58:32 EDT 2008


[NOR] cfi_cmdset_0001.c: Max timeouts for erase and write operations

This patch uses data from the CFI query structure to set
max timeouts for erase and write operations.

Signed-off-by: Anders Grafström <grfstrm at users.sourceforge.net>
---
  drivers/mtd/chips/cfi_cmdset_0001.c |   58 +++++++++++++++++++++++++---------
  include/linux/mtd/flashchip.h       |    4 ++
  2 files changed, 46 insertions(+), 16 deletions(-)

diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c
index fcd1aec..51f411a 100644
--- a/drivers/mtd/chips/cfi_cmdset_0001.c
+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
@@ -476,6 +476,27 @@ struct mtd_info *cfi_cmdset_0001(struct map_info *map, int primary)
  		else
  			cfi->chips[i].erase_time = 2000000;

+		if (cfi->cfiq->WordWriteTimeoutTyp &&
+		    cfi->cfiq->WordWriteTimeoutMax)
+			cfi->chips[i].word_write_timeout =
+				1<<(cfi->cfiq->WordWriteTimeoutTyp +
+				    cfi->cfiq->WordWriteTimeoutMax);
+		else
+			cfi->chips[i].word_write_timeout = 50000;
+
+		if (cfi->cfiq->BufWriteTimeoutTyp &&
+		    cfi->cfiq->BufWriteTimeoutMax)
+			cfi->chips[i].buffer_write_timeout =
+				1<<(cfi->cfiq->BufWriteTimeoutTyp +
+				    cfi->cfiq->BufWriteTimeoutMax);
+
+		if (cfi->cfiq->BlockEraseTimeoutTyp)
+			cfi->chips[i].erase_timeout =
+				1000<<(cfi->cfiq->BlockEraseTimeoutTyp +
+				       cfi->cfiq->BlockEraseTimeoutMax);
+		else
+			cfi->chips[i].erase_timeout = 2000000;
+
  		cfi->chips[i].ref_point_counter = 0;
  		init_waitqueue_head(&(cfi->chips[i].wq));
  	}
@@ -1010,7 +1031,7 @@ static void __xipram xip_enable(struct map_info *map, struct flchip *chip,

  static int __xipram xip_wait_for_operation(
  		struct map_info *map, struct flchip *chip,
-		unsigned long adr, unsigned int chip_op_time )
+		unsigned long adr, unsigned int chip_op_timeout)
  {
  	struct cfi_private *cfi = map->fldrv_priv;
  	struct cfi_pri_intelext *cfip = cfi->cmdset_priv;
@@ -1019,7 +1040,7 @@ static int __xipram xip_wait_for_operation(
  	flstate_t oldstate, newstate;

         	start = xip_currtime();
-	usec = chip_op_time * 8;
+	usec = chip_op_timeout;
  	if (usec == 0)
  		usec = 500000;
  	done = 0;
@@ -1129,8 +1150,8 @@ static int __xipram xip_wait_for_operation(
  #define XIP_INVAL_CACHED_RANGE(map, from, size)  \
  	INVALIDATE_CACHED_RANGE(map, from, size)

-#define INVAL_CACHE_AND_WAIT(map, chip, cmd_adr, inval_adr, inval_len, usec) \
-	xip_wait_for_operation(map, chip, cmd_adr, usec)
+#define INVAL_CACHE_AND_WAIT(map, chip, cmd_adr, inval_adr, inval_len, usec, usec_max) \
+	xip_wait_for_operation(map, chip, cmd_adr, usec_max)

  #else

@@ -1142,7 +1163,7 @@ static int __xipram xip_wait_for_operation(
  static int inval_cache_and_wait_for_operation(
  		struct map_info *map, struct flchip *chip,
  		unsigned long cmd_adr, unsigned long inval_adr, int inval_len,
-		unsigned int chip_op_time)
+		unsigned int chip_op_time, unsigned int chip_op_timeout)
  {
  	struct cfi_private *cfi = map->fldrv_priv;
  	map_word status, status_OK = CMD(0x80);
@@ -1154,11 +1175,13 @@ static int inval_cache_and_wait_for_operation(
  		INVALIDATE_CACHED_RANGE(map, inval_adr, inval_len);
  	spin_lock(chip->mutex);

-	/* set our timeout to 8 times the expected delay */
-	timeo = chip_op_time * 8;
-	if (!timeo)
+	if (!chip_op_time || !chip_op_timeout) {
  		timeo = 500000;
-	sleep_time = chip_op_time / 2;
+		sleep_time = 0;
+	} else {
+		timeo = chip_op_timeout;
+		sleep_time = chip_op_time / 2;
+	}

  	for (;;) {
  		status = map_read(map, cmd_adr);
@@ -1208,8 +1231,8 @@ static int inval_cache_and_wait_for_operation(

  #endif

-#define WAIT_TIMEOUT(map, chip, adr, udelay) \
-	INVAL_CACHE_AND_WAIT(map, chip, adr, 0, 0, udelay);
+#define WAIT_TIMEOUT(map, chip, adr, udelay, udelay_max) \
+	INVAL_CACHE_AND_WAIT(map, chip, adr, 0, 0, udelay, udelay_max);


  static int do_point_onechip (struct map_info *map, struct flchip *chip, loff_t adr, size_t len)
@@ -1443,7 +1466,8 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,

  	ret = INVAL_CACHE_AND_WAIT(map, chip, adr,
  				   adr, map_bankwidth(map),
-				   chip->word_write_time);
+				   chip->word_write_time,
+				   chip->word_write_timeout);
  	if (ret) {
  		xip_enable(map, chip, adr);
  		printk(KERN_ERR "%s: word write error (status timeout)\n", map->name);
@@ -1614,7 +1638,7 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,

  	chip->state = FL_WRITING_TO_BUFFER;
  	map_write(map, write_cmd, cmd_adr);
-	ret = WAIT_TIMEOUT(map, chip, cmd_adr, 0);
+	ret = WAIT_TIMEOUT(map, chip, cmd_adr, 0, 0);
  	if (ret) {
  		/* Argh. Not ready for write to buffer */
  		map_word Xstatus = map_read(map, cmd_adr);
@@ -1683,7 +1707,8 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,

  	ret = INVAL_CACHE_AND_WAIT(map, chip, cmd_adr,
  				   initial_adr, initial_len,
-				   chip->buffer_write_time);
+				   chip->buffer_write_time,
+				   chip->buffer_write_timeout);
  	if (ret) {
  		map_write(map, CMD(0x70), cmd_adr);
  		chip->state = FL_STATUS;
@@ -1818,7 +1843,8 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,

  	ret = INVAL_CACHE_AND_WAIT(map, chip, adr,
  				   adr, len,
-				   chip->erase_time);
+				   chip->erase_time,
+				   chip->erase_timeout);
  	if (ret) {
  		map_write(map, CMD(0x70), adr);
  		chip->state = FL_STATUS;
@@ -1997,7 +2023,7 @@ static int __xipram do_xxlock_oneblock(struct map_info *map, struct flchip *chip
  	 */
  	udelay = (!extp || !(extp->FeatureSupport & (1 << 5))) ? 1000000/HZ : 0;

-	ret = WAIT_TIMEOUT(map, chip, adr, udelay);
+	ret = WAIT_TIMEOUT(map, chip, adr, udelay, udelay);
  	if (ret) {
  		map_write(map, CMD(0x70), adr);
  		chip->state = FL_STATUS;
diff --git a/include/linux/mtd/flashchip.h b/include/linux/mtd/flashchip.h
index 39e7d2a..0299699 100644
--- a/include/linux/mtd/flashchip.h
+++ b/include/linux/mtd/flashchip.h
@@ -76,6 +76,10 @@ struct flchip {
  	int buffer_write_time;
  	int erase_time;

+	int word_write_timeout;
+	int buffer_write_timeout;
+	int erase_timeout;
+
  	void *priv;
  };

-- 
1.5.4.4




More information about the linux-mtd mailing list