Commit 92e73d80 authored by William A. Kennington III's avatar William A. Kennington III Committed by Wolfram Sang
Browse files

i2c: npcm7xx: Fix callback completion ordering



Sometimes, our completions race with new master transfers and override
the bus->operation and bus->master_or_slave variables. This causes
transactions to timeout and kernel crashes less frequently.

To remedy this, we re-order all completions to the very end of the
function.

Fixes: 56a1485b ("i2c: npcm7xx: Add Nuvoton NPCM I2C controller driver")
Signed-off-by: default avatarWilliam A. Kennington III <william@wkennington.com>
Reviewed-by: default avatarTali Perry <tali.perry1@gmail.com>
Signed-off-by: default avatarWolfram Sang <wsa@kernel.org>
parent b13e59e7
Loading
Loading
Loading
Loading
+7 −10
Original line number Diff line number Diff line
@@ -694,6 +694,7 @@ static void npcm_i2c_callback(struct npcm_i2c *bus,
{
	struct i2c_msg *msgs;
	int msgs_num;
	bool do_complete = false;

	msgs = bus->msgs;
	msgs_num = bus->msgs_num;
@@ -722,23 +723,17 @@ static void npcm_i2c_callback(struct npcm_i2c *bus,
				 msgs[1].flags & I2C_M_RD)
				msgs[1].len = info;
		}
		if (completion_done(&bus->cmd_complete) == false)
			complete(&bus->cmd_complete);
		do_complete = true;
		break;

	case I2C_NACK_IND:
		/* MASTER transmit got a NACK before tx all bytes */
		bus->cmd_err = -ENXIO;
		if (bus->master_or_slave == I2C_MASTER)
			complete(&bus->cmd_complete);

		do_complete = true;
		break;
	case I2C_BUS_ERR_IND:
		/* Bus error */
		bus->cmd_err = -EAGAIN;
		if (bus->master_or_slave == I2C_MASTER)
			complete(&bus->cmd_complete);

		do_complete = true;
		break;
	case I2C_WAKE_UP_IND:
		/* I2C wake up */
@@ -752,6 +747,8 @@ static void npcm_i2c_callback(struct npcm_i2c *bus,
	if (bus->slave)
		bus->master_or_slave = I2C_SLAVE;
#endif
	if (do_complete)
		complete(&bus->cmd_complete);
}

static u8 npcm_i2c_fifo_usage(struct npcm_i2c *bus)