Re: [PATCH v1 1/3] dmaengine: qcom: gpi: Add I2C bus recovery opcode support

From: Aniket RANDIVE

Date: Fri Oct 09 2026 - 01:36:12 EST




On 9/7/2026 10:44 AM, Mukesh Savaliya wrote:


On 8/26/2026 3:21 PM, Aniket Randive wrote:
The I2C_BUS_CLEAR and I2C_STOP_ON_BUS GENI sequencer opcodes release a
stuck I2C bus, but the GPI DMA driver has no way to emit these
zero-payload control commands, so an I2C controller using GPI DMA
cannot recover the bus.

Add I2C_BUS_CLEAR and I2C_STOP_ON_BUS to enum i2c_op so I2C drivers can
request them through gpi_i2c_config.op. Handle them in
gpi_create_i2c_tre() by emitting a CONFIG TRE (when set_config is set)
followed by a GO TRE with IEOT set and no DMA TRE, and reserve the
matching number of ring entries in gpi_prep_slave_sg().


start with problem statement which is being fixed by the respective patch.

Rest of the message can be simplified as below - more you can add.

Allow GPI DMA clients to issue the GENI I2C_BUS_CLEAR and
I2C_STOP_ON_BUS commands used for I2C bus recovery.

Add the new opcodes to the GPI I2C interface and generate the
corresponding CONFIG/GO TRE sequence without data DMA transfers.
Adjust TRE reservation logic to account for these commands.


I will update the commit message.

Signed-off-by: Aniket Randive <aniket.randive@xxxxxxxxxxxxxxxx>
---
  drivers/dma/qcom/gpi.c           | 30 ++++++++++++++++++++++++++++++
  include/linux/dma/qcom-gpi-dma.h |  2 ++
  2 files changed, 32 insertions(+)

diff --git a/drivers/dma/qcom/gpi.c b/drivers/dma/qcom/gpi.c

[...]

@@ -1825,6 +1843,18 @@ gpi_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
          nr_tre = 2;
      if (direction == DMA_DEV_TO_MEM) /* rx */
          nr_tre = 1;
+    /*
+     * Recovery opcodes do not require DMA data TREs, only CONFIG
+     * (for set_config) and GO TREs. Since gpi_prep_slave_sg() is
+     * shared with SPI, verify the channel is I2C before accessing
Not only SPI, its for all GENI protocols. Can say common function for all protocols.


sure. I will make it generic instead of single protocol.
May be once such conditions are rising, we need to think of better way in design to handle such cases.
+     * the configuration data.
+     */
+    if (gchan->protocol == QCOM_GPI_I2C) {
+        struct gpi_i2c_config *i2c = gchan->config;
+
+        if (i2c->op == I2C_BUS_CLEAR || i2c->op == I2C_STOP_ON_BUS)
+            nr_tre = set_config ? 2 : 1;
+    }

[...]