Commit 4a8e0f87 authored by Dmitry Osipenko's avatar Dmitry Osipenko Committed by Wolfram Sang
Browse files

i2c: tegra: Factor out error recovery from tegra_i2c_xfer_msg()



Factor out error recovery code from tegra_i2c_xfer_msg() in order to
make this function easier to read and follow.

Reviewed-by: default avatarMichał Mirosław <mirq-linux@rere.qmqm.pl>
Reviewed-by: default avatarAndy Shevchenko <andy.shevchenko@gmail.com>
Acked-by: default avatarThierry Reding <treding@nvidia.com>
Tested-by: default avatarThierry Reding <treding@nvidia.com>
Signed-off-by: default avatarDmitry Osipenko <digetx@gmail.com>
Signed-off-by: default avatarWolfram Sang <wsa@kernel.org>
parent e57ac5ab
Loading
Loading
Loading
Loading
+30 −16
Original line number Diff line number Diff line
@@ -1105,6 +1105,32 @@ static int tegra_i2c_issue_bus_clear(struct i2c_adapter *adap)
	return -EAGAIN;
}

static int tegra_i2c_error_recover(struct tegra_i2c_dev *i2c_dev,
				   struct i2c_msg *msg)
{
	if (i2c_dev->msg_err == I2C_ERR_NONE)
		return 0;

	tegra_i2c_init(i2c_dev);

	/* start recovery upon arbitration loss in single master mode */
	if (i2c_dev->msg_err == I2C_ERR_ARBITRATION_LOST) {
		if (!i2c_dev->is_multimaster_mode)
			return i2c_recover_bus(&i2c_dev->adapter);

		return -EAGAIN;
	}

	if (i2c_dev->msg_err == I2C_ERR_NO_ACK) {
		if (msg->flags & I2C_M_IGNORE_NAK)
			return 0;

		return -EREMOTEIO;
	}

	return -EIO;
}

static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
			      struct i2c_msg *msg,
			      enum msg_end_type end_state)
@@ -1288,24 +1314,12 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
		i2c_dev->msg_err);

	i2c_dev->is_curr_dma_xfer = false;
	if (i2c_dev->msg_err == I2C_ERR_NONE)
		return 0;

	tegra_i2c_init(i2c_dev);
	/* start recovery upon arbitration loss in single master mode */
	if (i2c_dev->msg_err == I2C_ERR_ARBITRATION_LOST) {
		if (!i2c_dev->is_multimaster_mode)
			return i2c_recover_bus(&i2c_dev->adapter);
		return -EAGAIN;
	}
	err = tegra_i2c_error_recover(i2c_dev, msg);
	if (err)
		return err;

	if (i2c_dev->msg_err == I2C_ERR_NO_ACK) {
		if (msg->flags & I2C_M_IGNORE_NAK)
	return 0;
		return -EREMOTEIO;
	}

	return -EIO;
}

static int tegra_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],