mirror of
https://github.com/torvalds/linux
synced 2024-11-05 18:23:50 +00:00
mtd: cfi_cmdset_0002: Move and rename chip_check/chip_ready/chip_good_for_write
This is a preparation patch for the S29GL064N buffer writes fix. There is no functional change. Link: https://lore.kernel.org/r/b687c259-6413-26c9-d4c9-b3afa69ea124@pengutronix.de/ Fixes: dfeae1073583("mtd: cfi_cmdset_0002: Change write buffer to check correct value") Signed-off-by: Tokunori Ikegami <ikegami.t@gmail.com> Cc: stable@vger.kernel.org Acked-by: Vignesh Raghavendra <vigneshr@ti.com> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com> Link: https://lore.kernel.org/linux-mtd/20220323170458.5608-2-ikegami.t@gmail.com
This commit is contained in:
parent
aa641a22bb
commit
083084df57
1 changed files with 35 additions and 66 deletions
|
@ -801,47 +801,11 @@ static struct mtd_info *cfi_amdstd_setup(struct mtd_info *mtd)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return true if the chip is ready.
|
||||
*
|
||||
* Ready is one of: read mode, query mode, erase-suspend-read mode (in any
|
||||
* non-suspended sector) and is indicated by no toggle bits toggling.
|
||||
*
|
||||
* Note that anything more complicated than checking if no bits are toggling
|
||||
* (including checking DQ5 for an error status) is tricky to get working
|
||||
* correctly and is therefore not done (particularly with interleaved chips
|
||||
* as each chip must be checked independently of the others).
|
||||
*/
|
||||
static int __xipram chip_ready(struct map_info *map, struct flchip *chip,
|
||||
unsigned long addr)
|
||||
{
|
||||
struct cfi_private *cfi = map->fldrv_priv;
|
||||
map_word d, t;
|
||||
|
||||
if (cfi_use_status_reg(cfi)) {
|
||||
map_word ready = CMD(CFI_SR_DRB);
|
||||
/*
|
||||
* For chips that support status register, check device
|
||||
* ready bit
|
||||
*/
|
||||
cfi_send_gen_cmd(0x70, cfi->addr_unlock1, chip->start, map, cfi,
|
||||
cfi->device_type, NULL);
|
||||
d = map_read(map, addr);
|
||||
|
||||
return map_word_andequal(map, d, ready, ready);
|
||||
}
|
||||
|
||||
d = map_read(map, addr);
|
||||
t = map_read(map, addr);
|
||||
|
||||
return map_word_equal(map, d, t);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return true if the chip is ready and has the correct value.
|
||||
*
|
||||
* Ready is one of: read mode, query mode, erase-suspend-read mode (in any
|
||||
* non-suspended sector) and it is indicated by no bits toggling.
|
||||
* non-suspended sector) and is indicated by no toggle bits toggling.
|
||||
*
|
||||
* Error are indicated by toggling bits or bits held with the wrong value,
|
||||
* or with bits toggling.
|
||||
|
@ -850,33 +814,36 @@ static int __xipram chip_ready(struct map_info *map, struct flchip *chip,
|
|||
* (including checking DQ5 for an error status) is tricky to get working
|
||||
* correctly and is therefore not done (particularly with interleaved chips
|
||||
* as each chip must be checked independently of the others).
|
||||
*
|
||||
*/
|
||||
static int __xipram chip_good(struct map_info *map, struct flchip *chip,
|
||||
unsigned long addr, map_word expected)
|
||||
static int __xipram chip_ready(struct map_info *map, struct flchip *chip,
|
||||
unsigned long addr, map_word *expected)
|
||||
{
|
||||
struct cfi_private *cfi = map->fldrv_priv;
|
||||
map_word oldd, curd;
|
||||
map_word d, t;
|
||||
int ret;
|
||||
|
||||
if (cfi_use_status_reg(cfi)) {
|
||||
map_word ready = CMD(CFI_SR_DRB);
|
||||
|
||||
/*
|
||||
* For chips that support status register, check device
|
||||
* ready bit
|
||||
*/
|
||||
cfi_send_gen_cmd(0x70, cfi->addr_unlock1, chip->start, map, cfi,
|
||||
cfi->device_type, NULL);
|
||||
curd = map_read(map, addr);
|
||||
t = map_read(map, addr);
|
||||
|
||||
return map_word_andequal(map, curd, ready, ready);
|
||||
return map_word_andequal(map, t, ready, ready);
|
||||
}
|
||||
|
||||
oldd = map_read(map, addr);
|
||||
curd = map_read(map, addr);
|
||||
d = map_read(map, addr);
|
||||
t = map_read(map, addr);
|
||||
|
||||
return map_word_equal(map, oldd, curd) &&
|
||||
map_word_equal(map, curd, expected);
|
||||
ret = map_word_equal(map, d, t);
|
||||
|
||||
if (!ret || !expected)
|
||||
return ret;
|
||||
|
||||
return map_word_equal(map, t, *expected);
|
||||
}
|
||||
|
||||
static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr, int mode)
|
||||
|
@ -893,7 +860,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
|
|||
|
||||
case FL_STATUS:
|
||||
for (;;) {
|
||||
if (chip_ready(map, chip, adr))
|
||||
if (chip_ready(map, chip, adr, NULL))
|
||||
break;
|
||||
|
||||
if (time_after(jiffies, timeo)) {
|
||||
|
@ -932,7 +899,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
|
|||
chip->state = FL_ERASE_SUSPENDING;
|
||||
chip->erase_suspended = 1;
|
||||
for (;;) {
|
||||
if (chip_ready(map, chip, adr))
|
||||
if (chip_ready(map, chip, adr, NULL))
|
||||
break;
|
||||
|
||||
if (time_after(jiffies, timeo)) {
|
||||
|
@ -1463,7 +1430,7 @@ static int do_otp_lock(struct map_info *map, struct flchip *chip, loff_t adr,
|
|||
/* wait for chip to become ready */
|
||||
timeo = jiffies + msecs_to_jiffies(2);
|
||||
for (;;) {
|
||||
if (chip_ready(map, chip, adr))
|
||||
if (chip_ready(map, chip, adr, NULL))
|
||||
break;
|
||||
|
||||
if (time_after(jiffies, timeo)) {
|
||||
|
@ -1695,11 +1662,11 @@ static int __xipram do_write_oneword_once(struct map_info *map,
|
|||
}
|
||||
|
||||
/*
|
||||
* We check "time_after" and "!chip_good" before checking
|
||||
* "chip_good" to avoid the failure due to scheduling.
|
||||
* We check "time_after" and "!chip_ready" before checking
|
||||
* "chip_ready" to avoid the failure due to scheduling.
|
||||
*/
|
||||
if (time_after(jiffies, timeo) &&
|
||||
!chip_good(map, chip, adr, datum)) {
|
||||
!chip_ready(map, chip, adr, &datum)) {
|
||||
xip_enable(map, chip, adr);
|
||||
printk(KERN_WARNING "MTD %s(): software timeout\n", __func__);
|
||||
xip_disable(map, chip, adr);
|
||||
|
@ -1707,7 +1674,7 @@ static int __xipram do_write_oneword_once(struct map_info *map,
|
|||
break;
|
||||
}
|
||||
|
||||
if (chip_good(map, chip, adr, datum)) {
|
||||
if (chip_ready(map, chip, adr, &datum)) {
|
||||
if (cfi_check_err_status(map, chip, adr))
|
||||
ret = -EIO;
|
||||
break;
|
||||
|
@ -1975,18 +1942,18 @@ static int __xipram do_write_buffer_wait(struct map_info *map,
|
|||
}
|
||||
|
||||
/*
|
||||
* We check "time_after" and "!chip_good" before checking
|
||||
* "chip_good" to avoid the failure due to scheduling.
|
||||
* We check "time_after" and "!chip_ready" before checking
|
||||
* "chip_ready" to avoid the failure due to scheduling.
|
||||
*/
|
||||
if (time_after(jiffies, timeo) &&
|
||||
!chip_good(map, chip, adr, datum)) {
|
||||
!chip_ready(map, chip, adr, &datum)) {
|
||||
pr_err("MTD %s(): software timeout, address:0x%.8lx.\n",
|
||||
__func__, adr);
|
||||
ret = -EIO;
|
||||
break;
|
||||
}
|
||||
|
||||
if (chip_good(map, chip, adr, datum)) {
|
||||
if (chip_ready(map, chip, adr, &datum)) {
|
||||
if (cfi_check_err_status(map, chip, adr))
|
||||
ret = -EIO;
|
||||
break;
|
||||
|
@ -2195,7 +2162,7 @@ static int cfi_amdstd_panic_wait(struct map_info *map, struct flchip *chip,
|
|||
* If the driver thinks the chip is idle, and no toggle bits
|
||||
* are changing, then the chip is actually idle for sure.
|
||||
*/
|
||||
if (chip->state == FL_READY && chip_ready(map, chip, adr))
|
||||
if (chip->state == FL_READY && chip_ready(map, chip, adr, NULL))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
|
@ -2212,7 +2179,7 @@ static int cfi_amdstd_panic_wait(struct map_info *map, struct flchip *chip,
|
|||
|
||||
/* wait for the chip to become ready */
|
||||
for (i = 0; i < jiffies_to_usecs(timeo); i++) {
|
||||
if (chip_ready(map, chip, adr))
|
||||
if (chip_ready(map, chip, adr, NULL))
|
||||
return 0;
|
||||
|
||||
udelay(1);
|
||||
|
@ -2276,13 +2243,13 @@ static int do_panic_write_oneword(struct map_info *map, struct flchip *chip,
|
|||
map_write(map, datum, adr);
|
||||
|
||||
for (i = 0; i < jiffies_to_usecs(uWriteTimeout); i++) {
|
||||
if (chip_ready(map, chip, adr))
|
||||
if (chip_ready(map, chip, adr, NULL))
|
||||
break;
|
||||
|
||||
udelay(1);
|
||||
}
|
||||
|
||||
if (!chip_good(map, chip, adr, datum) ||
|
||||
if (!chip_ready(map, chip, adr, &datum) ||
|
||||
cfi_check_err_status(map, chip, adr)) {
|
||||
/* reset on all failures. */
|
||||
map_write(map, CMD(0xF0), chip->start);
|
||||
|
@ -2424,6 +2391,7 @@ static int __xipram do_erase_chip(struct map_info *map, struct flchip *chip)
|
|||
DECLARE_WAITQUEUE(wait, current);
|
||||
int ret;
|
||||
int retry_cnt = 0;
|
||||
map_word datum = map_word_ff(map);
|
||||
|
||||
adr = cfi->addr_unlock1;
|
||||
|
||||
|
@ -2478,7 +2446,7 @@ static int __xipram do_erase_chip(struct map_info *map, struct flchip *chip)
|
|||
chip->erase_suspended = 0;
|
||||
}
|
||||
|
||||
if (chip_good(map, chip, adr, map_word_ff(map))) {
|
||||
if (chip_ready(map, chip, adr, &datum)) {
|
||||
if (cfi_check_err_status(map, chip, adr))
|
||||
ret = -EIO;
|
||||
break;
|
||||
|
@ -2523,6 +2491,7 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
|
|||
DECLARE_WAITQUEUE(wait, current);
|
||||
int ret;
|
||||
int retry_cnt = 0;
|
||||
map_word datum = map_word_ff(map);
|
||||
|
||||
adr += chip->start;
|
||||
|
||||
|
@ -2577,7 +2546,7 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
|
|||
chip->erase_suspended = 0;
|
||||
}
|
||||
|
||||
if (chip_good(map, chip, adr, map_word_ff(map))) {
|
||||
if (chip_ready(map, chip, adr, &datum)) {
|
||||
if (cfi_check_err_status(map, chip, adr))
|
||||
ret = -EIO;
|
||||
break;
|
||||
|
@ -2771,7 +2740,7 @@ static int __maybe_unused do_ppb_xxlock(struct map_info *map,
|
|||
*/
|
||||
timeo = jiffies + msecs_to_jiffies(2000); /* 2s max (un)locking */
|
||||
for (;;) {
|
||||
if (chip_ready(map, chip, adr))
|
||||
if (chip_ready(map, chip, adr, NULL))
|
||||
break;
|
||||
|
||||
if (time_after(jiffies, timeo)) {
|
||||
|
|
Loading…
Reference in a new issue