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

Commit 2db39a2f authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull i2c fixes from Wolfram Sang:

 - I2C core bugfix regarding bus recovery

 - driver bugfix for the tegra driver

 - typo correction

* 'i2c/for-current' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux:
  i2c: recovery: if possible send STOP with recovery pulses
  i2c: tegra: Fix NACK error handling
  i2c: stu300: use non-archaic spelling of failes
parents 3951dbf2 abe41184
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -127,7 +127,7 @@ enum stu300_error {

/*
 * The number of address send athemps tried before giving up.
 * If the first one failes it seems like 5 to 8 attempts are required.
 * If the first one fails it seems like 5 to 8 attempts are required.
 */
#define NUM_ADDR_RESEND_ATTEMPTS 12

+8 −9
Original line number Diff line number Diff line
@@ -545,6 +545,14 @@ static int tegra_i2c_disable_packet_mode(struct tegra_i2c_dev *i2c_dev)
{
	u32 cnfg;

	/*
	 * NACK interrupt is generated before the I2C controller generates
	 * the STOP condition on the bus. So wait for 2 clock periods
	 * before disabling the controller so that the STOP condition has
	 * been delivered properly.
	 */
	udelay(DIV_ROUND_UP(2 * 1000000, i2c_dev->bus_clk_rate));

	cnfg = i2c_readl(i2c_dev, I2C_CNFG);
	if (cnfg & I2C_CNFG_PACKET_MODE_EN)
		i2c_writel(i2c_dev, cnfg & ~I2C_CNFG_PACKET_MODE_EN, I2C_CNFG);
@@ -706,15 +714,6 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
	if (likely(i2c_dev->msg_err == I2C_ERR_NONE))
		return 0;

	/*
	 * NACK interrupt is generated before the I2C controller generates
	 * the STOP condition on the bus. So wait for 2 clock periods
	 * before resetting the controller so that the STOP condition has
	 * been delivered properly.
	 */
	if (i2c_dev->msg_err == I2C_ERR_NO_ACK)
		udelay(DIV_ROUND_UP(2 * 1000000, i2c_dev->bus_clk_rate));

	tegra_i2c_init(i2c_dev);
	if (i2c_dev->msg_err == I2C_ERR_NO_ACK) {
		if (msg->flags & I2C_M_IGNORE_NAK)
+10 −1
Original line number Diff line number Diff line
@@ -198,7 +198,16 @@ int i2c_generic_scl_recovery(struct i2c_adapter *adap)

		val = !val;
		bri->set_scl(adap, val);
		ndelay(RECOVERY_NDELAY);

		/*
		 * If we can set SDA, we will always create STOP here to ensure
		 * the additional pulses will do no harm. This is achieved by
		 * letting SDA follow SCL half a cycle later.
		 */
		ndelay(RECOVERY_NDELAY / 2);
		if (bri->set_sda)
			bri->set_sda(adap, val);
		ndelay(RECOVERY_NDELAY / 2);
	}

	/* check if recovery actually succeeded */