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

Commit ae899e25 authored by Subbaraman Narayanamurthy's avatar Subbaraman Narayanamurthy Committed by Harry Yang
Browse files

qcom: fg-memif: improve retry mechanism for IMA read/write



FG SRAM read/write APIs consist of peripheral/supporting
read/writes and the core interleaved_mem_access functions.

The current implementation retries only when the core functions
return an error and in case of a read, additionally when the beat
count changes. This works except if the peripheral/supporting
access fail, we do not even retry.

Introduce retries for all possible failures while reading/writing
a SRAM location.

Change-Id: I99ad9acae3ef0dbc3941094076f124d16099468c
Signed-off-by: default avatarSubbaraman Narayanamurthy <subbaram@codeaurora.org>
parent 95450d67
Loading
Loading
Loading
Loading
+44 −15
Original line number Diff line number Diff line
@@ -289,7 +289,7 @@ static int fg_check_iacs_ready(struct fg_chip *chip)
	}

	if (!tries) {
		pr_err("IACS_RDY not set\n");
		pr_err("IACS_RDY not set, opr_sts: %d\n", ima_opr_sts);
		/* check for error condition */
		rc = fg_clear_ima_errors_if_any(chip, false);
		if (rc < 0) {
@@ -546,7 +546,7 @@ int fg_interleaved_mem_read(struct fg_chip *chip, u16 address, u8 offset,
{
	int rc = 0, ret;
	u8 start_beat_count, end_beat_count, count = 0;
	bool retry_once = false;
	bool retry = false;

	if (offset > 3) {
		pr_err("offset too large %d\n", offset);
@@ -554,10 +554,18 @@ int fg_interleaved_mem_read(struct fg_chip *chip, u16 address, u8 offset,
	}

retry:
	if (count >= RETRY_COUNT) {
		pr_err("Tried %d times\n", RETRY_COUNT);
		retry = false;
		goto out;
	}

	rc = fg_interleaved_mem_config(chip, val, address, offset, len,
					FG_READ);
	if (rc < 0) {
		pr_err("failed to configure SRAM for IMA rc = %d\n", rc);
		count++;
		retry = true;
		goto out;
	}

@@ -565,18 +573,21 @@ int fg_interleaved_mem_read(struct fg_chip *chip, u16 address, u8 offset,
	rc = fg_get_beat_count(chip, &start_beat_count);
	if (rc < 0) {
		pr_err("failed to read beat count rc=%d\n", rc);
		count++;
		retry = true;
		goto out;
	}

	/* read data */
	rc = __fg_interleaved_mem_read(chip, address, offset, val, len);
	if (rc < 0) {
		if ((rc == -EAGAIN) && (count < RETRY_COUNT)) {
		count++;
		if (rc == -EAGAIN) {
			pr_err("IMA access failed retry_count = %d\n", count);
			goto retry;
		}
		pr_err("failed to read SRAM address rc = %d\n", rc);
		retry = true;
		goto out;
	}

@@ -584,32 +595,31 @@ int fg_interleaved_mem_read(struct fg_chip *chip, u16 address, u8 offset,
	rc = fg_get_beat_count(chip, &end_beat_count);
	if (rc < 0) {
		pr_err("failed to read beat count rc=%d\n", rc);
		count++;
		retry = true;
		goto out;
	}

	fg_dbg(chip, FG_SRAM_READ, "Start beat_count = %x End beat_count = %x\n",
		start_beat_count, end_beat_count);

	if (start_beat_count != end_beat_count && !retry_once) {
	if (start_beat_count != end_beat_count) {
		fg_dbg(chip, FG_SRAM_READ, "Beat count(%d/%d) do not match - retry transaction\n",
			start_beat_count, end_beat_count);
		retry_once = true;
		count++;
		retry = true;
	}
out:
	/* Release IMA access */
	ret = fg_masked_write(chip, MEM_IF_MEM_INTF_CFG(chip),
				MEM_ACCESS_REQ_BIT | IACS_SLCT_BIT, 0);
	if (ret < 0) {
	if (rc < 0 && ret < 0) {
		pr_err("failed to reset IMA access bit ret = %d\n", ret);
		return ret;
	}

	/* Return the error we got before releasing memory access */
	if (rc < 0)
		return rc;

	if (retry_once) {
		retry_once = false;
	if (retry) {
		retry = false;
		goto retry;
	}

@@ -621,6 +631,7 @@ int fg_interleaved_mem_write(struct fg_chip *chip, u16 address, u8 offset,
{
	int rc = 0, ret;
	u8 start_beat_count, end_beat_count, count = 0;
	bool retry = false;

	if (offset > 3) {
		pr_err("offset too large %d\n", offset);
@@ -628,10 +639,18 @@ int fg_interleaved_mem_write(struct fg_chip *chip, u16 address, u8 offset,
	}

retry:
	if (count >= RETRY_COUNT) {
		pr_err("Tried %d times\n", RETRY_COUNT);
		retry = false;
		goto out;
	}

	rc = fg_interleaved_mem_config(chip, val, address, offset, len,
					FG_WRITE);
	if (rc < 0) {
		pr_err("failed to configure SRAM for IMA rc = %d\n", rc);
		count++;
		retry = true;
		goto out;
	}

@@ -639,18 +658,21 @@ int fg_interleaved_mem_write(struct fg_chip *chip, u16 address, u8 offset,
	rc = fg_get_beat_count(chip, &start_beat_count);
	if (rc < 0) {
		pr_err("failed to read beat count rc=%d\n", rc);
		count++;
		retry = true;
		goto out;
	}

	/* write data */
	rc = __fg_interleaved_mem_write(chip, address, offset, val, len);
	if (rc < 0) {
		if ((rc == -EAGAIN) && (count < RETRY_COUNT)) {
		count++;
		if ((rc == -EAGAIN) && (count < RETRY_COUNT)) {
			pr_err("IMA access failed retry_count = %d\n", count);
			goto retry;
		}
		pr_err("failed to write SRAM address rc = %d\n", rc);
		retry = true;
		goto out;
	}

@@ -658,6 +680,8 @@ int fg_interleaved_mem_write(struct fg_chip *chip, u16 address, u8 offset,
	rc = fg_get_beat_count(chip, &end_beat_count);
	if (rc < 0) {
		pr_err("failed to read beat count rc=%d\n", rc);
		count++;
		retry = true;
		goto out;
	}

@@ -668,11 +692,16 @@ int fg_interleaved_mem_write(struct fg_chip *chip, u16 address, u8 offset,
	/* Release IMA access */
	ret = fg_masked_write(chip, MEM_IF_MEM_INTF_CFG(chip),
				MEM_ACCESS_REQ_BIT | IACS_SLCT_BIT, 0);
	if (ret < 0) {
	if (rc < 0 && ret < 0) {
		pr_err("failed to reset IMA access bit ret = %d\n", ret);
		return ret;
	}

	if (retry) {
		retry = false;
		goto retry;
	}

	/* Return the error we got before releasing memory access */
	return rc;
}