Re: [PATCH v1 1/3] dmaengine: qcom: gpi: Add I2C bus recovery opcode support
From: Mukesh Savaliya
Date: Mon Sep 07 2026 - 01:14:40 EST
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.
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,Not only SPI, its for all GENI protocols. Can say common function for all protocols.
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
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;
+ }
[...]