lkml.org 
[lkml]   [2019]   [Nov]   [21]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
From
SubjectRe: [PATCH 4.19 127/422] i2c: mediatek: Use DMA safe buffers for i2c transactions
On Wed, Nov 20, 2019 at 10:44:06AM +0900, Nobuhiro Iwamatsu wrote:
> 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;
> > + }
> > +
> > + rpaddr = dma_map_single(i2c->dev, dma_rd_buf,
> > (msgs + 1)->len,
> > DMA_FROM_DEVICE);
> > if (dma_mapping_error(i2c->dev, rpaddr)) {
> > dma_unmap_single(i2c->dev, wpaddr,
> > msgs->len, DMA_TO_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);
> > +
> > + i2c_put_dma_safe_msg_buf(dma_wr_buf, msgs, true);
> > } 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_rd_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_wr_buf, msgs, true);
> > + i2c_put_dma_safe_msg_buf(dma_rd_buf, (msgs + 1), true);
> > }
> >
> > if (ret == 0) {
> > --
> > 2.20.1

Now queued up, thanks.

greg k-h

\
 
 \ /
  Last update: 2019-11-21 07:54    [W:0.635 / U:0.032 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site