Re: [PATCH v1] i2c: qcom-geni: Skip extra TX DMA TRE for single read message in GPI mode

From: Mukesh Kumar Savaliya

Date: Fri Mar 27 2026 - 02:55:27 EST




On 3/26/2026 10:01 AM, Aniket Randive wrote:
In GPI mode, the I2C GENI driver incorrectly generates an extra TX DMA
TRE on the TX channel during single read message transfer. This results
What's the impact of this extra DMA TRE ? do you see failure/timeout, anything ?
in an unnecessary write operation on the I2C bus, which is not required.

Update the logic to avoid generating the extra TX DMA TRE for single
read message, ensuring correct behavior and preventing redundant
transfers.

So for read, we do unwanted write too ? if so, please write it accordingly. Correct behavior needs to be justified against wrong.
Co-developed-by: Maramaina Naresh <naresh.maramaina@xxxxxxxxxxxxxxxx>
Signed-off-by: Maramaina Naresh <naresh.maramaina@xxxxxxxxxxxxxxxx>
Signed-off-by: Aniket Randive <aniket.randive@xxxxxxxxxxxxxxxx>
---
drivers/i2c/busses/i2c-qcom-geni.c | 18 +++++++++++++-----
1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/drivers/i2c/busses/i2c-qcom-geni.c b/drivers/i2c/busses/i2c-qcom-geni.c
index a4acb78fafb6..2706309bbebb 100644
--- a/drivers/i2c/busses/i2c-qcom-geni.c
+++ b/drivers/i2c/busses/i2c-qcom-geni.c
@@ -625,8 +625,8 @@ static int geni_i2c_gpi(struct geni_i2c_dev *gi2c, struct i2c_msg msgs[],
{
struct gpi_i2c_config *peripheral;
unsigned int flags;
- void *dma_buf;
- dma_addr_t addr;
+ void *dma_buf = NULL;
+ dma_addr_t addr = 0;
enum dma_data_direction map_dirn;
enum dma_transfer_direction dma_dirn;
struct dma_async_tx_descriptor *desc;
@@ -639,6 +639,11 @@ static int geni_i2c_gpi(struct geni_i2c_dev *gi2c, struct i2c_msg msgs[],
gi2c_gpi_xfer = &gi2c->i2c_multi_desc_config;
msg_idx = gi2c_gpi_xfer->msg_idx_cnt;
+ if (op == I2C_WRITE && msgs[msg_idx].flags & I2C_M_RD) {
+ peripheral->multi_msg = true;
what's the actual meaning of multi_msg here ? IIUC, this multi_msg is set to true for single transfer ? any better name if so ? Yes, need to change it out of this patch.
+ goto skip_dma;
+ }
+
dma_buf = i2c_get_dma_safe_msg_buf(&msgs[msg_idx], 1);
if (!dma_buf) {
ret = -ENOMEM;
@@ -668,6 +673,7 @@ static int geni_i2c_gpi(struct geni_i2c_dev *gi2c, struct i2c_msg msgs[],
flags = DMA_PREP_INTERRUPT | DMA_CTRL_ACK;
}
+skip_dma:
/* set the length as message for rx txn */
peripheral->rx_len = msgs[msg_idx].len;
peripheral->op = op;
@@ -740,9 +746,11 @@ static int geni_i2c_gpi(struct geni_i2c_dev *gi2c, struct i2c_msg msgs[],
return 0;
err_config:
- dma_unmap_single(gi2c->se.dev->parent, addr,
- msgs[msg_idx].len, map_dirn);
- i2c_put_dma_safe_msg_buf(dma_buf, &msgs[msg_idx], false);
+ if (op == I2C_WRITE && (msgs[msg_idx].flags & I2C_M_RD)) {
+ dma_unmap_single(gi2c->se.dev->parent, addr,
+ msgs[msg_idx].len, map_dirn);
+ i2c_put_dma_safe_msg_buf(dma_buf, &msgs[msg_idx], false);
+ }
out:
gi2c->err = ret;

---
base-commit: 785f0eb2f85decbe7c1ef9ae922931f0194ffc2e
change-id: 20260325-skip_extra_dma_tre-a3cf22f81d9b

Best regards,
--
Aniket Randive <aniket.randive@xxxxxxxxxxxxxxxx>