Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f2c2ad53 authored by Tokunori Ikegami's avatar Tokunori Ikegami Committed by Greg Kroah-Hartman
Browse files

mtd: cfi_cmdset_0002: Move and rename chip_check/chip_ready/chip_good_for_write

commit 083084df578a8bdb18334f69e7b32d690aaa3247 upstream.

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: dfeae107("mtd: cfi_cmdset_0002: Change write buffer to check correct value")
Signed-off-by: default avatarTokunori Ikegami <ikegami.t@gmail.com>
Cc: stable@vger.kernel.org
Acked-by: default avatarVignesh Raghavendra <vigneshr@ti.com>
Signed-off-by: default avatarMiquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/linux-mtd/20220323170458.5608-2-ikegami.t@gmail.com


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 16e993ac
Loading
Loading
Loading
Loading
+32 −63
Original line number Diff line number Diff line
@@ -798,21 +798,25 @@ static struct mtd_info *cfi_amdstd_setup(struct mtd_info *mtd)
}

/*
 * Return true if the chip is ready.
 * 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 is indicated by no toggle bits toggling.
 *
 * Error are indicated by toggling bits or bits held with the wrong value,
 * or with 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)
			       unsigned long addr, map_word *expected)
{
	struct cfi_private *cfi = map->fldrv_priv;
	map_word d, t;
	int ret;

	if (cfi_use_status_reg(cfi)) {
		map_word ready = CMD(CFI_SR_DRB);
@@ -822,57 +826,20 @@ static int __xipram chip_ready(struct map_info *map, struct flchip *chip,
		 */
		cfi_send_gen_cmd(0x70, cfi->addr_unlock1, chip->start, map, cfi,
				 cfi->device_type, NULL);
		d = map_read(map, addr);
		t = map_read(map, addr);

		return map_word_andequal(map, d, ready, ready);
		return map_word_andequal(map, t, 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.
 *
 * Error are indicated by toggling bits or bits held with the wrong value,
 * or with 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_good(struct map_info *map, struct flchip *chip,
			      unsigned long addr, map_word expected)
{
	struct cfi_private *cfi = map->fldrv_priv;
	map_word oldd, curd;

	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);

		return map_word_andequal(map, curd, ready, ready);
	}
	ret = map_word_equal(map, d, t);

	oldd = map_read(map, addr);
	curd = map_read(map, addr);
	if (!ret || !expected)
		return ret;

	return	map_word_equal(map, oldd, curd) &&
		map_word_equal(map, curd, expected);
	return map_word_equal(map, t, *expected);
}

static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr, int mode)
@@ -889,7 +856,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)) {
@@ -927,7 +894,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)) {
@@ -1459,7 +1426,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)) {
@@ -1691,11 +1658,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);
@@ -1703,7 +1670,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;
@@ -1971,18 +1938,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;
@@ -2191,7 +2158,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;

	/*
@@ -2208,7 +2175,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);
@@ -2272,13 +2239,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);
@@ -2420,6 +2387,7 @@ static int __xipram do_erase_chip(struct map_info *map, struct flchip *chip)
	DECLARE_WAITQUEUE(wait, current);
	int ret = 0;
	int retry_cnt = 0;
	map_word datum = map_word_ff(map);

	adr = cfi->addr_unlock1;

@@ -2474,7 +2442,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;
@@ -2519,6 +2487,7 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
	DECLARE_WAITQUEUE(wait, current);
	int ret = 0;
	int retry_cnt = 0;
	map_word datum = map_word_ff(map);

	adr += chip->start;

@@ -2573,7 +2542,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;
@@ -2767,7 +2736,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)) {