* [PATCH v2 1/4] i2c: octeon: Fix infinite loop in clock divisor calculation
2026-11-13 13:41 [PATCH v2 0/4] i2c: octeon/thunderx: Fix DMA mask + improvements Paul Cercueil
@ 2026-11-13 13:41 ` Paul Cercueil
2026-11-13 13:41 ` [PATCH v2 2/4] i2c: octeon: Add error state recovery Paul Cercueil
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Paul Cercueil @ 2026-11-13 13:41 UTC (permalink / raw)
To: Robert Richter, Andi Shyti
Cc: linux-i2c, linux-kernel, Thomas Petazzoni, Sunil Kovvuri Goutham,
Umesh Kumar, Shashank Gupta, Tanmay Jagdale, stable,
Paul Cercueil
From: Tanmay Jagdale <tanmay@marvell.com>
When mdiv_min is unsigned, the signed mdiv_idx variable is cast to
unsigned as well in the inner loop condition comparison, leading to an
infinite loop.
Fixes: 03240f826b02 ("i2c: thunderx: Support for High speed mode")
Cc: stable@vger.kernel.org
Signed-off-by: Tanmay Jagdale <tanmay@marvell.com>
Co-developed-by: Paul Cercueil <paul.cercueil@bootlin.com>
Signed-off-by: Paul Cercueil <paul.cercueil@bootlin.com>
---
v2: New patch
---
drivers/i2c/busses/i2c-octeon-core.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/i2c/busses/i2c-octeon-core.c b/drivers/i2c/busses/i2c-octeon-core.c
index 93a49e4637ec..85e18ca2410e 100644
--- a/drivers/i2c/busses/i2c-octeon-core.c
+++ b/drivers/i2c/busses/i2c-octeon-core.c
@@ -823,14 +823,14 @@ int octeon_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
/* calculate and set clock divisors */
void octeon_i2c_set_clock(struct octeon_i2c *i2c)
{
- int tclk, thp_base, inc, thp_idx, mdiv_idx, ndiv_idx, foscl, diff;
+ int tclk, thp_base, inc, thp_idx, mdiv_idx, mdiv_min, ndiv_idx, foscl, diff;
bool is_plat_otx2;
/*
* Find divisors to produce target frequency, start with large delta
* to cover wider range of divisors, note thp = TCLK half period and
* ds is OSCL output frequency divisor.
*/
- unsigned int thp, mdiv_min, mdiv = 2, ndiv = 0, ds = 10;
+ unsigned int thp, mdiv = 2, ndiv = 0, ds = 10;
unsigned int delta_hz = INITIAL_DELTA_HZ;
is_plat_otx2 = octeon_i2c_is_otx2(to_pci_dev(i2c->dev));
--
2.47.3
^ permalink raw reply [flat|nested] 5+ messages in thread* [PATCH v2 2/4] i2c: octeon: Add error state recovery
2026-11-13 13:41 [PATCH v2 0/4] i2c: octeon/thunderx: Fix DMA mask + improvements Paul Cercueil
2026-11-13 13:41 ` [PATCH v2 1/4] i2c: octeon: Fix infinite loop in clock divisor calculation Paul Cercueil
@ 2026-11-13 13:41 ` Paul Cercueil
2026-11-13 13:41 ` [PATCH v2 3/4] i2c: thunderx: Set DMA mask Paul Cercueil
2026-11-13 13:41 ` [PATCH v2 4/4] i2c: thunderx: Use polling with delay in HS mode Paul Cercueil
3 siblings, 0 replies; 5+ messages in thread
From: Paul Cercueil @ 2026-11-13 13:41 UTC (permalink / raw)
To: Robert Richter, Andi Shyti
Cc: linux-i2c, linux-kernel, Thomas Petazzoni, Sunil Kovvuri Goutham,
Umesh Kumar, Shashank Gupta, Tanmay Jagdale, Paul Cercueil
From: Tanmay Jagdale <tanmay@marvell.com>
Whenever a Bus Error state occurs, trigger a software recovery to
attempt to return to a working state.
Signed-off-by: Tanmay Jagdale <tanmay@marvell.com>
Co-developed-by: Paul Cercueil <paul.cercueil@bootlin.com>
Signed-off-by: Paul Cercueil <paul.cercueil@bootlin.com>
---
v2: No change
---
drivers/i2c/busses/i2c-octeon-core.c | 27 ++++++++++++++-------------
1 file changed, 14 insertions(+), 13 deletions(-)
diff --git a/drivers/i2c/busses/i2c-octeon-core.c b/drivers/i2c/busses/i2c-octeon-core.c
index 85e18ca2410e..c4f80d178c2a 100644
--- a/drivers/i2c/busses/i2c-octeon-core.c
+++ b/drivers/i2c/busses/i2c-octeon-core.c
@@ -205,6 +205,17 @@ static int octeon_i2c_hlc_wait(struct octeon_i2c *i2c)
return 0;
}
+static int octeon_i2c_recovery(struct octeon_i2c *i2c)
+{
+ int ret;
+
+ ret = i2c_recover_bus(&i2c->adap);
+ if (ret)
+ /* recover failed, try hardware re-init */
+ ret = octeon_i2c_init_lowlevel(i2c);
+ return ret;
+}
+
static int octeon_i2c_check_status(struct octeon_i2c *i2c, int final_read)
{
u8 stat;
@@ -265,8 +276,9 @@ static int octeon_i2c_check_status(struct octeon_i2c *i2c, int final_read)
return -EOPNOTSUPP;
case STAT_TXDATA_NAK:
- case STAT_BUS_ERROR:
return -EIO;
+ case STAT_BUS_ERROR:
+ return octeon_i2c_recovery(i2c) ? -EIO : -EAGAIN;
case STAT_TXADDR_NAK:
case STAT_RXADDR_NAK:
case STAT_AD2W_NAK:
@@ -277,24 +289,13 @@ static int octeon_i2c_check_status(struct octeon_i2c *i2c, int final_read)
/* Set BUS_MON_RST to reset bus monitor */
mode |= BUS_MON_RST_MASK;
octeon_i2c_writeq_flush(mode, i2c->twsi_base + OCTEON_REG_MODE(i2c));
- return -EIO;
+ return octeon_i2c_recovery(i2c) ? -EIO : -EAGAIN;
default:
dev_err(i2c->dev, "unhandled state: %d\n", stat);
return -EIO;
}
}
-static int octeon_i2c_recovery(struct octeon_i2c *i2c)
-{
- int ret;
-
- ret = i2c_recover_bus(&i2c->adap);
- if (ret)
- /* recover failed, try hardware re-init */
- ret = octeon_i2c_init_lowlevel(i2c);
- return ret;
-}
-
/**
* octeon_i2c_start - send START to the bus
* @i2c: The struct octeon_i2c
--
2.47.3
^ permalink raw reply [flat|nested] 5+ messages in thread* [PATCH v2 3/4] i2c: thunderx: Set DMA mask
2026-11-13 13:41 [PATCH v2 0/4] i2c: octeon/thunderx: Fix DMA mask + improvements Paul Cercueil
2026-11-13 13:41 ` [PATCH v2 1/4] i2c: octeon: Fix infinite loop in clock divisor calculation Paul Cercueil
2026-11-13 13:41 ` [PATCH v2 2/4] i2c: octeon: Add error state recovery Paul Cercueil
@ 2026-11-13 13:41 ` Paul Cercueil
2026-11-13 13:41 ` [PATCH v2 4/4] i2c: thunderx: Use polling with delay in HS mode Paul Cercueil
3 siblings, 0 replies; 5+ messages in thread
From: Paul Cercueil @ 2026-11-13 13:41 UTC (permalink / raw)
To: Robert Richter, Andi Shyti
Cc: linux-i2c, linux-kernel, Thomas Petazzoni, Sunil Kovvuri Goutham,
Umesh Kumar, Shashank Gupta, Tanmay Jagdale, stable,
Paul Cercueil
From: Tanmay Jagdale <tanmay@marvell.com>
Without it, MSI-X initialization can fail.
Fixes: 4c21541d8da1 ("i2c: thunderx: Replace pci_enable_msix()")
Cc: stable@vger.kernel.org
Signed-off-by: Tanmay Jagdale <tanmay@marvell.com>
Co-developed-by: Paul Cercueil <paul.cercueil@bootlin.com>
Signed-off-by: Paul Cercueil <paul.cercueil@bootlin.com>
---
v2: No change
---
drivers/i2c/busses/i2c-thunderx-pcidrv.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/i2c/busses/i2c-thunderx-pcidrv.c b/drivers/i2c/busses/i2c-thunderx-pcidrv.c
index 3959f23fc440..2208337e649b 100644
--- a/drivers/i2c/busses/i2c-thunderx-pcidrv.c
+++ b/drivers/i2c/busses/i2c-thunderx-pcidrv.c
@@ -198,6 +198,10 @@ static int thunder_i2c_probe_pci(struct pci_dev *pdev,
i2c->hlc_int_enable = thunder_i2c_hlc_int_enable;
i2c->hlc_int_disable = thunder_i2c_hlc_int_disable;
+ ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(48));
+ if (ret < 0)
+ goto error;
+
ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_MSIX);
if (ret < 0)
goto error;
--
2.47.3
^ permalink raw reply [flat|nested] 5+ messages in thread* [PATCH v2 4/4] i2c: thunderx: Use polling with delay in HS mode
2026-11-13 13:41 [PATCH v2 0/4] i2c: octeon/thunderx: Fix DMA mask + improvements Paul Cercueil
` (2 preceding siblings ...)
2026-11-13 13:41 ` [PATCH v2 3/4] i2c: thunderx: Set DMA mask Paul Cercueil
@ 2026-11-13 13:41 ` Paul Cercueil
3 siblings, 0 replies; 5+ messages in thread
From: Paul Cercueil @ 2026-11-13 13:41 UTC (permalink / raw)
To: Robert Richter, Andi Shyti
Cc: linux-i2c, linux-kernel, Thomas Petazzoni, Sunil Kovvuri Goutham,
Umesh Kumar, Shashank Gupta, Tanmay Jagdale, Paul Cercueil
From: Tanmay Jagdale <tanmay@marvell.com>
High I2C transaction latencies exceeding 1 second were intermittently
observed while operating in HS mode. These delays caused DTLS handshakes
between the main processor and firmware processors to time out,
resulting in increased startup time.
Replace the existing wait mechanism with delayed polling in HS mode to
improve transfer responsiveness and avoid prolonged latency spikes.
Signed-off-by: Tanmay Jagdale <tanmay@marvell.com>
Co-developed-by: Paul Cercueil <paul.cercueil@bootlin.com>
Signed-off-by: Paul Cercueil <paul.cercueil@bootlin.com>
---
v2: No change
---
drivers/i2c/busses/i2c-octeon-core.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/i2c/busses/i2c-octeon-core.c b/drivers/i2c/busses/i2c-octeon-core.c
index c4f80d178c2a..9ef3306e57a0 100644
--- a/drivers/i2c/busses/i2c-octeon-core.c
+++ b/drivers/i2c/busses/i2c-octeon-core.c
@@ -15,6 +15,7 @@
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
+#include <linux/iopoll.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
@@ -65,6 +66,9 @@ static int octeon_i2c_wait(struct octeon_i2c *i2c)
return octeon_i2c_test_iflg(i2c) ? 0 : -ETIMEDOUT;
}
+ if (!IS_LS_FREQ(i2c->twsi_freq))
+ return poll_timeout_us_atomic(, octeon_i2c_test_iflg(i2c), 1, 1000, false);
+
i2c->int_enable(i2c);
time_left = wait_event_timeout(i2c->queue, octeon_i2c_test_iflg(i2c),
i2c->adap.timeout);
--
2.47.3
^ permalink raw reply [flat|nested] 5+ messages in thread