2018-09-06 13:18:50

by Jun Gao

[permalink] [raw]
Subject: [PATCH v3 0/2] Register i2c adapter driver earlier and use DMA safe buffers

This patch series based on v4.19-rc2, include i2c adapter driver register time
modification and DMA safe buffers used for i2c transactions.

changes since v2:
- Remove the patch i2c: Add helper to ease DMA handling
- Use i2c refactor function to release a DMA safe buffer

changes since v1:
- Add the initializations for DMA safe buffer pointers

Jun Gao (2):
i2c: mediatek: Register i2c adapter driver earlier
i2c: mediatek: Use DMA safe buffers for i2c transactions

drivers/i2c/busses/i2c-mt65xx.c | 74 ++++++++++++++++++++++++++++++++++++-----
1 file changed, 66 insertions(+), 8 deletions(-)

--
1.8.1.1



2018-09-06 13:19:10

by Jun Gao

[permalink] [raw]
Subject: [PATCH v3 2/2] i2c: mediatek: Use DMA safe buffers for i2c transactions

From: Jun Gao <[email protected]>

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 <[email protected]>
---
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 806e8b90..695a2ae 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) {
--
1.8.1.1


2018-09-06 19:42:09

by Jun Gao

[permalink] [raw]
Subject: [PATCH v3 1/2] i2c: mediatek: Register i2c adapter driver earlier

From: Jun Gao <[email protected]>

In order not to block the initializations of some i2c devices.
Register i2c adapter driver at appropriate time.

Signed-off-by: Jun Gao <[email protected]>
---
drivers/i2c/busses/i2c-mt65xx.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c
index 1e57f58..806e8b90 100644
--- a/drivers/i2c/busses/i2c-mt65xx.c
+++ b/drivers/i2c/busses/i2c-mt65xx.c
@@ -888,7 +888,17 @@ static int mtk_i2c_resume(struct device *dev)
},
};

-module_platform_driver(mtk_i2c_driver);
+static int __init mtk_i2c_adap_init(void)
+{
+ return platform_driver_register(&mtk_i2c_driver);
+}
+subsys_initcall(mtk_i2c_adap_init);
+
+static void __exit mtk_i2c_adap_exit(void)
+{
+ platform_driver_unregister(&mtk_i2c_driver);
+}
+module_exit(mtk_i2c_adap_exit);

MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("MediaTek I2C Bus Driver");
--
1.8.1.1


2018-09-06 22:17:48

by Wolfram Sang

[permalink] [raw]
Subject: Re: [PATCH v3 2/2] i2c: mediatek: Use DMA safe buffers for i2c transactions

On Thu, Sep 06, 2018 at 09:15:29PM +0800, Jun Gao wrote:
> From: Jun Gao <[email protected]>
>
> 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 <[email protected]>

Applied to for-next, thanks!


Attachments:
(No filename) (330.00 B)
signature.asc (849.00 B)
Download all attachments

2018-09-06 23:00:15

by Wolfram Sang

[permalink] [raw]
Subject: Re: [PATCH v3 1/2] i2c: mediatek: Register i2c adapter driver earlier

On Thu, Sep 06, 2018 at 09:15:28PM +0800, Jun Gao wrote:
> From: Jun Gao <[email protected]>
>
> In order not to block the initializations of some i2c devices.
> Register i2c adapter driver at appropriate time.
>
> Signed-off-by: Jun Gao <[email protected]>

The reasons this patch was rejected in v2 still hold.


Attachments:
(No filename) (332.00 B)
signature.asc (849.00 B)
Download all attachments

2018-09-11 02:27:12

by Jun Gao

[permalink] [raw]
Subject: Re: [PATCH v3 1/2] i2c: mediatek: Register i2c adapter driver earlier

On Thu, 2018-09-06 at 20:31 +0200, Wolfram Sang wrote:
> On Thu, Sep 06, 2018 at 09:15:28PM +0800, Jun Gao wrote:
> > From: Jun Gao <[email protected]>
> >
> > In order not to block the initializations of some i2c devices.
> > Register i2c adapter driver at appropriate time.
> >
> > Signed-off-by: Jun Gao <[email protected]>
>
> The reasons this patch was rejected in v2 still hold.
OK. Thanks for your opinion.
>