Skip to content

Commit b492183

Browse files
leilkliuWolfram Sang
authored andcommitted
i2c: mediatek: fix potential incorrect use of I2C_MASTER_WRRD
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>
1 parent 1a2b423 commit b492183

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
@@ -1243,6 +1243,7 @@ static int mtk_i2c_transfer(struct i2c_adapter *adap,
12431243
{
12441244
int ret;
12451245
int left_num = num;
1246+
bool write_then_read_en = false;
12461247
struct mtk_i2c *i2c = i2c_get_adapdata(adap);
12471248

12481249
ret = clk_bulk_enable(I2C_MT65XX_CLK_MAX, i2c->clocks);
@@ -1256,6 +1257,7 @@ static int mtk_i2c_transfer(struct i2c_adapter *adap,
12561257
if (!(msgs[0].flags & I2C_M_RD) && (msgs[1].flags & I2C_M_RD) &&
12571258
msgs[0].addr == msgs[1].addr) {
12581259
i2c->auto_restart = 0;
1260+
write_then_read_en = true;
12591261
}
12601262
}
12611263

@@ -1280,20 +1282,21 @@ static int mtk_i2c_transfer(struct i2c_adapter *adap,
12801282
else
12811283
i2c->op = I2C_MASTER_WR;
12821284

1283-
if (!i2c->auto_restart) {
1284-
if (num > 1) {
1285-
/* combined two messages into one transaction */
1286-
i2c->op = I2C_MASTER_WRRD;
1287-
left_num--;
1288-
}
1285+
if (write_then_read_en) {
1286+
/* combined two messages into one transaction */
1287+
i2c->op = I2C_MASTER_WRRD;
1288+
left_num--;
12891289
}
12901290

12911291
/* always use DMA mode. */
12921292
ret = mtk_i2c_do_transfer(i2c, msgs, num, left_num);
12931293
if (ret < 0)
12941294
goto err_exit;
12951295

1296-
msgs++;
1296+
if (i2c->op == I2C_MASTER_WRRD)
1297+
msgs += 2;
1298+
else
1299+
msgs++;
12971300
}
12981301
/* the return value is number of executed messages */
12991302
ret = num;

0 commit comments

Comments
 (0)