mirror of
git://git.yoctoproject.org/linux-yocto.git
synced 2025-10-22 23:13:01 +02:00
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: b2ed11e224
("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>
This commit is contained in:
parent
e8de297fa4
commit
07f952d5d2
|
@ -1218,6 +1218,7 @@ static int mtk_i2c_transfer(struct i2c_adapter *adap,
|
|||
{
|
||||
int ret;
|
||||
int left_num = num;
|
||||
bool write_then_read_en = false;
|
||||
struct mtk_i2c *i2c = i2c_get_adapdata(adap);
|
||||
|
||||
ret = clk_bulk_enable(I2C_MT65XX_CLK_MAX, i2c->clocks);
|
||||
|
@ -1231,6 +1232,7 @@ static int mtk_i2c_transfer(struct i2c_adapter *adap,
|
|||
if (!(msgs[0].flags & I2C_M_RD) && (msgs[1].flags & I2C_M_RD) &&
|
||||
msgs[0].addr == msgs[1].addr) {
|
||||
i2c->auto_restart = 0;
|
||||
write_then_read_en = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1255,12 +1257,10 @@ static int mtk_i2c_transfer(struct i2c_adapter *adap,
|
|||
else
|
||||
i2c->op = I2C_MASTER_WR;
|
||||
|
||||
if (!i2c->auto_restart) {
|
||||
if (num > 1) {
|
||||
/* combined two messages into one transaction */
|
||||
i2c->op = I2C_MASTER_WRRD;
|
||||
left_num--;
|
||||
}
|
||||
if (write_then_read_en) {
|
||||
/* combined two messages into one transaction */
|
||||
i2c->op = I2C_MASTER_WRRD;
|
||||
left_num--;
|
||||
}
|
||||
|
||||
/* always use DMA mode. */
|
||||
|
@ -1268,7 +1268,10 @@ static int mtk_i2c_transfer(struct i2c_adapter *adap,
|
|||
if (ret < 0)
|
||||
goto err_exit;
|
||||
|
||||
msgs++;
|
||||
if (i2c->op == I2C_MASTER_WRRD)
|
||||
msgs += 2;
|
||||
else
|
||||
msgs++;
|
||||
}
|
||||
/* the return value is number of executed messages */
|
||||
ret = num;
|
||||
|
|
Loading…
Reference in New Issue
Block a user