Re: [PATCH v7 2/2] i2c: qcom-geni: Add dynamic transfer timeout based on transfer length and frequency
From: Aniket RANDIVE
Date: Wed Aug 26 2026 - 06:51:28 EST
Thanks Mukesh for the review.
On 8/24/2026 12:41 PM, Mukesh Savaliya wrote:
On 8/13/2026 11:15 AM, Aniket Randive wrote:
[...]
static int geni_i2c_gpi_multi_xfer_timeout_handler(struct device *dev,
struct geni_i2c_gpi_multi_desc_xfer *multi_xfer,
- u32 transfer_timeout_msecs,
+ unsigned long timeout_jiffies,
struct completion *transfer_comp)
{
int i;
- u32 time_left;
+ unsigned long time_left;
for (i = 0; i < multi_xfer->msg_idx_cnt - 1; i++) {
reinit_completion(transfer_comp);
if (multi_xfer->msg_idx_cnt != multi_xfer->irq_cnt) {
time_left = wait_for_completion_timeout(transfer_comp,
- transfer_timeout_msecs);
+ timeout_jiffies);
if (!time_left) {
dev_err(dev, "%s: Transfer timeout\n", __func__);
return -ETIMEDOUT;
@@ -778,8 +787,22 @@ static int geni_i2c_gpi(struct geni_i2c_dev *gi2c, struct i2c_msg msgs[],
dma_async_issue_pending(gi2c->tx_c);
if ((msg_idx == (gi2c->num_msgs - 1)) || flags & DMA_PREP_INTERRUPT) {
+ size_t max_len = 0;
+ int j;
+
+ /*
+ * Use the longest message as the timeout base: one completion
+ * covers the whole BEI batch, so the budget must fit the worst
+ * case single-message wire time.
+ */
Using only the longest message length may under-estimate the required Timeout.
Yes. We can take sum of all messages in GPI multi desc path. I will do this change in next patch.
+ for (j = 0; j < gi2c->num_msgs; j++)can we use sum(msgs[i].len) instead of max() ?> + i2c_update_timeout(&gi2c->adap, gi2c->clk_freq_out, max_len,
+ max_len = max_t(size_t, max_len, msgs[j].len);
+ I2C_TIMEOUT_SAFETY_COEFFICIENT,
+ I2C_TIMEOUT_MIN_USEC);
ret = geni_i2c_gpi_multi_xfer_timeout_handler(gi2c- >se.dev, gi2c_gpi_xfer,
- XFER_TIMEOUT, &gi2c->done);
+ gi2c->adap.timeout,
+ &gi2c->done);
if (ret) {
dev_err(gi2c->se.dev,
"I2C multi write msg transfer timeout: %d\n",
@@ -899,7 +922,10 @@ static int geni_i2c_gpi_xfer(struct geni_i2c_dev *gi2c, struct i2c_msg msgs[], i
if (!gi2c->is_tx_multi_desc_xfer) {
dma_async_issue_pending(gi2c->tx_c);
- time_left = wait_for_completion_timeout(&gi2c->done, XFER_TIMEOUT);
+ i2c_update_timeout(&gi2c->adap, gi2c->clk_freq_out, msgs[i].len,
+ I2C_TIMEOUT_SAFETY_COEFFICIENT,
+ I2C_TIMEOUT_MIN_USEC);
+ time_left = wait_for_completion_timeout(&gi2c->done, gi2c->adap.timeout);
if (!time_left) {
dev_err(gi2c->se.dev, "%s:I2C timeout\n", __func__);
gi2c->err = -ETIMEDOUT;