Skip to content

Commit b6eccd9

Browse files
leilkliuUlrich Hecht
authored andcommitted
i2c: mediatek: fix potential incorrect use of I2C_MASTER_WRRD
[ Upstream commit b492183652808e0f389272bf63dc836241b287ff ] The old IC does not support the I2C_MASTER_WRRD (write-then-read) function, but the current code’s handling of i2c->auto_restart may potentially lead to entering the I2C_MASTER_WRRD software flow, resulting in unexpected bugs. Instead of repurposing the auto_restart flag, add a separate flag to signal I2C_MASTER_WRRD operations. Also fix handling of msgs. If the operation (i2c->op) is I2C_MASTER_WRRD, then the msgs pointer is incremented by 2. For all other operations, msgs is simply incremented by 1. Fixes: b2ed11e ("I2C: mediatek: Add driver for MediaTek MT8173 I2C controller") Signed-off-by: Leilk.Liu <leilk.liu@mediatek.com> Suggested-by: Chen-Yu Tsai <wenst@chromium.org> Reviewed-by: Chen-Yu Tsai <wenst@chromium.org> Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com> Signed-off-by: Sasha Levin <sashal@kernel.org> Signed-off-by: Ulrich Hecht <uli@kernel.org>
1 parent 729f477 commit b6eccd9

1 file changed

Lines changed: 10 additions & 7 deletions

File tree

drivers/i2c/busses/i2c-mt65xx.c

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -658,6 +658,7 @@ static int mtk_i2c_transfer(struct i2c_adapter *adap,
658658
{
659659
int ret;
660660
int left_num = num;
661+
bool write_then_read_en = false;
661662
struct mtk_i2c *i2c = i2c_get_adapdata(adap);
662663

663664
ret = mtk_i2c_clock_enable(i2c);
@@ -671,6 +672,7 @@ static int mtk_i2c_transfer(struct i2c_adapter *adap,
671672
if (!(msgs[0].flags & I2C_M_RD) && (msgs[1].flags & I2C_M_RD) &&
672673
msgs[0].addr == msgs[1].addr) {
673674
i2c->auto_restart = 0;
675+
write_then_read_en = true;
674676
}
675677
}
676678

@@ -694,20 +696,21 @@ static int mtk_i2c_transfer(struct i2c_adapter *adap,
694696
else
695697
i2c->op = I2C_MASTER_WR;
696698

697-
if (!i2c->auto_restart) {
698-
if (num > 1) {
699-
/* combined two messages into one transaction */
700-
i2c->op = I2C_MASTER_WRRD;
701-
left_num--;
702-
}
699+
if (write_then_read_en) {
700+
/* combined two messages into one transaction */
701+
i2c->op = I2C_MASTER_WRRD;
702+
left_num--;
703703
}
704704

705705
/* always use DMA mode. */
706706
ret = mtk_i2c_do_transfer(i2c, msgs, num, left_num);
707707
if (ret < 0)
708708
goto err_exit;
709709

710-
msgs++;
710+
if (i2c->op == I2C_MASTER_WRRD)
711+
msgs += 2;
712+
else
713+
msgs++;
711714
}
712715
/* the return value is number of executed messages */
713716
ret = num;

0 commit comments

Comments
 (0)