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

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

qcom: fg-memif: Return error properly when IMA read/write fails



In the SRAM masked write we read the register first, make
modification to the value and write it back. If the read fails
we bail out of the masked write function.

However there is a bug in the read api where the error code is
not properly returned. This causes the masked write to proceed
with a failed read and corruption ensues.

A similar bug is present in write api too where the error is not
returned correctly to the caller. Fix this.

Change-Id: Ic7651c5cb2e054a0b8b2dfe201463063ce9e167b
Signed-off-by: default avatarSubbaraman Narayanamurthy <subbaram@codeaurora.org>
parent 2cdd1402
Loading
Loading
Loading
Loading
+17 −10
Original line number Diff line number Diff line
/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -544,7 +544,7 @@ static int fg_get_beat_count(struct fg_chip *chip, u8 *count)
int fg_interleaved_mem_read(struct fg_chip *chip, u16 address, u8 offset,
				u8 *val, int len)
{
	int rc = 0;
	int rc = 0, ret;
	u8 start_beat_count, end_beat_count, count = 0;
	bool retry_once = false;

@@ -597,13 +597,17 @@ int fg_interleaved_mem_read(struct fg_chip *chip, u16 address, u8 offset,
	}
out:
	/* Release IMA access */
	rc = fg_masked_write(chip, MEM_IF_MEM_INTF_CFG(chip),
	ret = fg_masked_write(chip, MEM_IF_MEM_INTF_CFG(chip),
				MEM_ACCESS_REQ_BIT | IACS_SLCT_BIT, 0);
	if (rc < 0) {
		pr_err("failed to reset IMA access bit rc = %d\n", rc);
		return rc;
	if (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;
		goto retry;
@@ -615,7 +619,7 @@ int fg_interleaved_mem_read(struct fg_chip *chip, u16 address, u8 offset,
int fg_interleaved_mem_write(struct fg_chip *chip, u16 address, u8 offset,
				u8 *val, int len, bool atomic_access)
{
	int rc = 0;
	int rc = 0, ret;
	u8 start_beat_count, end_beat_count, count = 0;

	if (offset > 3) {
@@ -662,11 +666,14 @@ int fg_interleaved_mem_write(struct fg_chip *chip, u16 address, u8 offset,
			start_beat_count, end_beat_count);
out:
	/* Release IMA access */
	rc = fg_masked_write(chip, MEM_IF_MEM_INTF_CFG(chip),
	ret = fg_masked_write(chip, MEM_IF_MEM_INTF_CFG(chip),
				MEM_ACCESS_REQ_BIT | IACS_SLCT_BIT, 0);
	if (rc < 0)
		pr_err("failed to reset IMA access bit rc = %d\n", rc);
	if (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 */
	return rc;
}