diff options
author | Tokunori Ikegami <ikegami.t@gmail.com> | 2019-08-05 22:03:24 +0300 |
---|---|---|
committer | Vignesh Raghavendra <vigneshr@ti.com> | 2019-08-27 15:25:53 +0300 |
commit | 6beb3ea746db88904a5ab8f2cc87837489e46612 (patch) | |
tree | 8cb15200707d81cf5c804200640450bcb114d624 /drivers/mtd/chips | |
parent | 816a6d1481a55983ba527a93702160cf210acade (diff) | |
download | linux-6beb3ea746db88904a5ab8f2cc87837489e46612.tar.xz |
mtd: cfi_cmdset_0002: Split wait for write buffer completion sequence
Split wait for write completion from do_write_buffer() into separate
function.
Cc: Fabio Bettoni <fbettoni@gmail.com>
Co: Hauke Mehrtens <hauke@hauke-m.de>
Cc: Chris Packham <chris.packham@alliedtelesis.co.nz>
Cc: Joakim Tjernlund <Joakim.Tjernlund@infinera.com>
Cc: linux-mtd@lists.infradead.org
Signed-off-by: Tokunori Ikegami <ikegami.t@gmail.com>
[vigneshr@ti.com: Reword commit message]
Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com>
Diffstat (limited to 'drivers/mtd/chips')
-rw-r--r-- | drivers/mtd/chips/cfi_cmdset_0002.c | 92 |
1 files changed, 51 insertions, 41 deletions
diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c index 8f0ee552837e..6f9f77dbc6d7 100644 --- a/drivers/mtd/chips/cfi_cmdset_0002.c +++ b/drivers/mtd/chips/cfi_cmdset_0002.c @@ -1919,6 +1919,56 @@ 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 u_write_timeout; + int ret = 0; + + /* + * Timeout is calculated according to CFI data, if available. + * See more comments in cfi_cmdset_0002(). + */ + u_write_timeout = usecs_to_jiffies(chip->buffer_write_time_max); + timeo = jiffies + u_write_timeout; + + 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, chip, adr, datum)) { + ret = -EIO; + break; + } + + if (chip_good(map, chip, 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) @@ -1949,13 +1999,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; @@ -2012,40 +2055,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, chip, adr, datum)) { - ret = -EIO; - break; - } - - if (chip_good(map, chip, 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) { cfi_check_err_status(map, chip, adr); do_write_buffer_reset(map, chip, cfi); |