Hi,
On Tue, Nov 19, 2019 at 06:15:24AM +0100, Greg Kroah-Hartman wrote:
From: Jun Gao jun.gao@mediatek.com
[ Upstream commit fc66b39fe36acfd06f716e338de7cd8f9550fad2 ]
DMA mode will always be used in i2c transactions, try to allocate a DMA safe buffer if the buf of struct i2c_msg used is not DMA safe.
Signed-off-by: Jun Gao jun.gao@mediatek.com Signed-off-by: Wolfram Sang wsa@the-dreams.de Signed-off-by: Sasha Levin sashal@kernel.org
This patch requires the following additional commit:
commit bc1a7f75c85e226e82f183d30d75c357f92b6029 Author: Hsin-Yi Wang hsinyi@chromium.org Date: Fri Feb 15 17:02:02 2019 +0800
i2c: mediatek: modify threshold passed to i2c_get_dma_safe_msg_buf()
DMA with zero-length transfers doesn't make sense and this HW doesn't support them at all, so increase the threshold.
Fixes: fc66b39fe36a ("i2c: mediatek: Use DMA safe buffers for i2c transactions") Signed-off-by: Hsin-Yi Wang hsinyi@chromium.org [wsa: reworded commit message] Signed-off-by: Wolfram Sang wsa@the-dreams.de
Please apply this commit.
Best regards, Nobuhiro
drivers/i2c/busses/i2c-mt65xx.c | 62 +++++++++++++++++++++++++++++---- 1 file changed, 55 insertions(+), 7 deletions(-)
diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c index 1e57f58fcb001..a74ef76705e0c 100644 --- a/drivers/i2c/busses/i2c-mt65xx.c +++ b/drivers/i2c/busses/i2c-mt65xx.c @@ -441,6 +441,8 @@ static int mtk_i2c_do_transfer(struct mtk_i2c *i2c, struct i2c_msg *msgs, u16 control_reg; u16 restart_flag = 0; u32 reg_4g_mode;
- u8 *dma_rd_buf = NULL;
- u8 *dma_wr_buf = NULL; dma_addr_t rpaddr = 0; dma_addr_t wpaddr = 0; int ret;
@@ -500,10 +502,18 @@ static int mtk_i2c_do_transfer(struct mtk_i2c *i2c, struct i2c_msg *msgs, if (i2c->op == I2C_MASTER_RD) { writel(I2C_DMA_INT_FLAG_NONE, i2c->pdmabase + OFFSET_INT_FLAG); writel(I2C_DMA_CON_RX, i2c->pdmabase + OFFSET_CON);
rpaddr = dma_map_single(i2c->dev, msgs->buf,
dma_rd_buf = i2c_get_dma_safe_msg_buf(msgs, 0);
if (!dma_rd_buf)
return -ENOMEM;
rpaddr = dma_map_single(i2c->dev, dma_rd_buf, msgs->len, DMA_FROM_DEVICE);
if (dma_mapping_error(i2c->dev, rpaddr))
if (dma_mapping_error(i2c->dev, rpaddr)) {
i2c_put_dma_safe_msg_buf(dma_rd_buf, msgs, false);
return -ENOMEM;
}
if (i2c->dev_comp->support_33bits) { reg_4g_mode = mtk_i2c_set_4g_mode(rpaddr); @@ -515,10 +525,18 @@ static int mtk_i2c_do_transfer(struct mtk_i2c *i2c, struct i2c_msg *msgs, } else if (i2c->op == I2C_MASTER_WR) { writel(I2C_DMA_INT_FLAG_NONE, i2c->pdmabase + OFFSET_INT_FLAG); writel(I2C_DMA_CON_TX, i2c->pdmabase + OFFSET_CON);
wpaddr = dma_map_single(i2c->dev, msgs->buf,
dma_wr_buf = i2c_get_dma_safe_msg_buf(msgs, 0);
if (!dma_wr_buf)
return -ENOMEM;
wpaddr = dma_map_single(i2c->dev, dma_wr_buf, msgs->len, DMA_TO_DEVICE);
if (dma_mapping_error(i2c->dev, wpaddr))
if (dma_mapping_error(i2c->dev, wpaddr)) {
i2c_put_dma_safe_msg_buf(dma_wr_buf, msgs, false);
return -ENOMEM;
}
if (i2c->dev_comp->support_33bits) { reg_4g_mode = mtk_i2c_set_4g_mode(wpaddr); @@ -530,16 +548,39 @@ static int mtk_i2c_do_transfer(struct mtk_i2c *i2c, struct i2c_msg *msgs, } else { writel(I2C_DMA_CLR_FLAG, i2c->pdmabase + OFFSET_INT_FLAG); writel(I2C_DMA_CLR_FLAG, i2c->pdmabase + OFFSET_CON);
wpaddr = dma_map_single(i2c->dev, msgs->buf,
dma_wr_buf = i2c_get_dma_safe_msg_buf(msgs, 0);
if (!dma_wr_buf)
return -ENOMEM;
wpaddr = dma_map_single(i2c->dev, dma_wr_buf, msgs->len, DMA_TO_DEVICE);
if (dma_mapping_error(i2c->dev, wpaddr))
if (dma_mapping_error(i2c->dev, wpaddr)) {
i2c_put_dma_safe_msg_buf(dma_wr_buf, msgs, false);
return -ENOMEM;
rpaddr = dma_map_single(i2c->dev, (msgs + 1)->buf,
}
dma_rd_buf = i2c_get_dma_safe_msg_buf((msgs + 1), 0);
if (!dma_rd_buf) {
dma_unmap_single(i2c->dev, wpaddr,
msgs->len, DMA_TO_DEVICE);
i2c_put_dma_safe_msg_buf(dma_wr_buf, msgs, false);
return -ENOMEM;
}
if (dma_mapping_error(i2c->dev, rpaddr)) { dma_unmap_single(i2c->dev, wpaddr, msgs->len, DMA_TO_DEVICE);rpaddr = dma_map_single(i2c->dev, dma_rd_buf, (msgs + 1)->len, DMA_FROM_DEVICE);
i2c_put_dma_safe_msg_buf(dma_wr_buf, msgs, false);
i2c_put_dma_safe_msg_buf(dma_rd_buf, (msgs + 1), false);
}return -ENOMEM;
@@ -578,14 +619,21 @@ static int mtk_i2c_do_transfer(struct mtk_i2c *i2c, struct i2c_msg *msgs, if (i2c->op == I2C_MASTER_WR) { dma_unmap_single(i2c->dev, wpaddr, msgs->len, DMA_TO_DEVICE);
} else if (i2c->op == I2C_MASTER_RD) { dma_unmap_single(i2c->dev, rpaddr, msgs->len, DMA_FROM_DEVICE);i2c_put_dma_safe_msg_buf(dma_wr_buf, msgs, true);
} else { dma_unmap_single(i2c->dev, wpaddr, msgs->len, DMA_TO_DEVICE); dma_unmap_single(i2c->dev, rpaddr, (msgs + 1)->len, DMA_FROM_DEVICE);i2c_put_dma_safe_msg_buf(dma_rd_buf, msgs, true);
i2c_put_dma_safe_msg_buf(dma_wr_buf, msgs, true);
}i2c_put_dma_safe_msg_buf(dma_rd_buf, (msgs + 1), true);
if (ret == 0) { -- 2.20.1