Just refactor to split the wait from do_write_buffer(). Signed-off-by: Tokunori Ikegami <ikegami.t@xxxxxxxxx> Cc: Fabio Bettoni <fbettoni@xxxxxxxxx> Co: Hauke Mehrtens <hauke@xxxxxxxxxx> Co: Koen Vandeputte <koen.vandeputte@xxxxxxxxxxxx> Cc: Chris Packham <chris.packham@xxxxxxxxxxxxxxxxxxx> Cc: Joakim Tjernlund <Joakim.Tjernlund@xxxxxxxxxxxx> Cc: linux-mtd@xxxxxxxxxxxxxxxxxxx --- Changes since v5: - Rebased on top of Liu Jian's fixes in master. - Change the email address of Tokunori Ikegami to ikegami.t@xxxxxxxxx. Changes since v4: - None. Changes since v3: - Just change the email address of Tokunori Ikegami to ikegami_to@xxxxxxxxxxx. Changes since v2: - None. Changes since v1: - Add the patch. drivers/mtd/chips/cfi_cmdset_0002.c | 89 +++++++++++++++++++++---------------- 1 file changed, 50 insertions(+), 39 deletions(-) diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c index a3e57788bc40..ebf420e1db43 100755 --- a/drivers/mtd/chips/cfi_cmdset_0002.c +++ b/drivers/mtd/chips/cfi_cmdset_0002.c @@ -1825,6 +1825,55 @@ static int cfi_amdstd_write_words(struct mtd_info *mtd, loff_t to, size_t len, return 0; } +static int __xipram do_write_buffer_wait(struct map_info *map, + struct flchip *chip, unsigned long adr, + map_word datum) +{ + unsigned long timeo; + unsigned long uWriteTimeout; + int ret = 0; + + /* + * Timeout is calculated according to CFI data, if available. + * See more comments in cfi_cmdset_0002(). + */ + uWriteTimeout = usecs_to_jiffies(chip->buffer_write_time_max); + timeo = jiffies + uWriteTimeout; + + for (;;) { + if (chip->state != FL_WRITING) { + /* Someone's suspended the write. Sleep */ + DECLARE_WAITQUEUE(wait, current); + + set_current_state(TASK_UNINTERRUPTIBLE); + add_wait_queue(&chip->wq, &wait); + mutex_unlock(&chip->mutex); + schedule(); + remove_wait_queue(&chip->wq, &wait); + timeo = jiffies + (HZ / 2); /* FIXME */ + mutex_lock(&chip->mutex); + continue; + } + + /* + * We check "time_after" and "!chip_good" before checking "chip_good" to avoid + * the failure due to scheduling. + */ + if (time_after(jiffies, timeo) && !chip_good(map, adr, datum)) { + ret = -EIO; + break; + } + + if (chip_good(map, adr, datum)) + break; + + /* Latency issues. Drop the lock, wait a while and retry */ + UDELAY(map, chip, adr, 1); + } + + return ret; +} + static void __xipram do_write_buffer_reset(struct map_info *map, struct flchip *chip, struct cfi_private *cfi) @@ -1855,13 +1904,6 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip, int len) { struct cfi_private *cfi = map->fldrv_priv; - unsigned long timeo = jiffies + HZ; - /* - * Timeout is calculated according to CFI data, if available. - * See more comments in cfi_cmdset_0002(). - */ - unsigned long uWriteTimeout = - usecs_to_jiffies(chip->buffer_write_time_max); int ret = -EIO; unsigned long cmd_adr; int z, words; @@ -1918,38 +1960,7 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip, adr, map_bankwidth(map), chip->word_write_time); - timeo = jiffies + uWriteTimeout; - - for (;;) { - if (chip->state != FL_WRITING) { - /* Someone's suspended the write. Sleep */ - DECLARE_WAITQUEUE(wait, current); - - set_current_state(TASK_UNINTERRUPTIBLE); - add_wait_queue(&chip->wq, &wait); - mutex_unlock(&chip->mutex); - schedule(); - remove_wait_queue(&chip->wq, &wait); - timeo = jiffies + (HZ / 2); /* FIXME */ - mutex_lock(&chip->mutex); - continue; - } - - /* - * We check "time_after" and "!chip_good" before checking "chip_good" to avoid - * the failure due to scheduling. - */ - if (time_after(jiffies, timeo) && !chip_good(map, adr, datum)) { - ret = -EIO; - break; - } - - if (chip_good(map, adr, datum)) - break; - - /* Latency issues. Drop the lock, wait a while and retry */ - UDELAY(map, chip, adr, 1); - } + ret = do_write_buffer_wait(map, chip, adr, datum); if (ret) { do_write_buffer_reset(map, chip, cfi); -- 2.11.0 ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/