Unverified Commit 5b74da8e authored by Troy Mitchell's avatar Troy Mitchell Committed by Andi Shyti
Browse files

i2c: spacemit: move i2c_xfer_msg()



The upcoming PIO support requires a wait_pio_xfer() helper, which is
invoked from xfer_msg().

Since wait_pio_xfer() depends on err_check(), move the definition of
xfer_msg() after err_check() to avoid a forward declaration of
err_check().

Reviewed-by: default avatarAurelien Jarno <aurelien@aurel32.net>
Reviewed-by: default avatarAlex Elder <elder@riscstar.com>
Signed-off-by: default avatarTroy Mitchell <troy.mitchell@linux.spacemit.com>
Tested-by: default avatarAurelien Jarno <aurelien@aurel32.net>
Signed-off-by: default avatarAndi Shyti <andi.shyti@kernel.org>
Link: https://lore.kernel.org/r/20260207-b4-k3-i2c-pio-v7-1-626942d94d91@linux.spacemit.com
parent dd0422eb
Loading
Loading
Loading
Loading
+31 −31
Original line number Diff line number Diff line
@@ -305,37 +305,6 @@ static void spacemit_i2c_start(struct spacemit_i2c_dev *i2c)
	writel(val, i2c->base + SPACEMIT_ICR);
}

static int spacemit_i2c_xfer_msg(struct spacemit_i2c_dev *i2c)
{
	unsigned long time_left;
	struct i2c_msg *msg;

	for (i2c->msg_idx = 0; i2c->msg_idx < i2c->msg_num; i2c->msg_idx++) {
		msg = &i2c->msgs[i2c->msg_idx];
		i2c->msg_buf = msg->buf;
		i2c->unprocessed = msg->len;
		i2c->status = 0;

		reinit_completion(&i2c->complete);

		spacemit_i2c_start(i2c);

		time_left = wait_for_completion_timeout(&i2c->complete,
							i2c->adapt.timeout);
		if (!time_left) {
			dev_err(i2c->dev, "msg completion timeout\n");
			spacemit_i2c_conditionally_reset_bus(i2c);
			spacemit_i2c_reset(i2c);
			return -ETIMEDOUT;
		}

		if (i2c->status & SPACEMIT_SR_ERR)
			return spacemit_i2c_handle_err(i2c);
	}

	return 0;
}

static bool spacemit_i2c_is_last_msg(struct spacemit_i2c_dev *i2c)
{
	if (i2c->msg_idx != i2c->msg_num - 1)
@@ -419,6 +388,37 @@ static void spacemit_i2c_err_check(struct spacemit_i2c_dev *i2c)
	complete(&i2c->complete);
}

static int spacemit_i2c_xfer_msg(struct spacemit_i2c_dev *i2c)
{
	unsigned long time_left;
	struct i2c_msg *msg;

	for (i2c->msg_idx = 0; i2c->msg_idx < i2c->msg_num; i2c->msg_idx++) {
		msg = &i2c->msgs[i2c->msg_idx];
		i2c->msg_buf = msg->buf;
		i2c->unprocessed = msg->len;
		i2c->status = 0;

		reinit_completion(&i2c->complete);

		spacemit_i2c_start(i2c);

		time_left = wait_for_completion_timeout(&i2c->complete,
							i2c->adapt.timeout);
		if (!time_left) {
			dev_err(i2c->dev, "msg completion timeout\n");
			spacemit_i2c_conditionally_reset_bus(i2c);
			spacemit_i2c_reset(i2c);
			return -ETIMEDOUT;
		}

		if (i2c->status & SPACEMIT_SR_ERR)
			return spacemit_i2c_handle_err(i2c);
	}

	return 0;
}

static irqreturn_t spacemit_i2c_irq_handler(int irq, void *devid)
{
	struct spacemit_i2c_dev *i2c = devid;