drivers: i2c: stm32: add timeout to avoid infinite loop

Fix issue where STM32 I2C LL driver could block forever when SDA and SCL
are shorted and interrupts are disabled (CONFIG_I2C_STM32_INTERRUPT=n).

Added timeouts to all blocking wait loops in the STM32 LL I2C driver to
avoid indefinite blocking.

Fixes #88506

Signed-off-by: Jean Nanchen <jean.nanchen@hevs.ch>
(cherry picked from commit 2066b8c7b9b5b149d6395a57282202c534f4eb8b)
diff --git a/drivers/i2c/i2c_ll_stm32_v2.c b/drivers/i2c/i2c_ll_stm32_v2.c
index 8e97fff..e4ec27d 100644
--- a/drivers/i2c/i2c_ll_stm32_v2.c
+++ b/drivers/i2c/i2c_ll_stm32_v2.c
@@ -745,17 +745,26 @@
 {
 	const struct i2c_stm32_config *cfg = dev->config;
 	I2C_TypeDef *i2c = cfg->i2c;
+	int64_t start_time = k_uptime_get();
 
 	/* Wait for transfer to complete */
 	while (!LL_I2C_IsActiveFlag_TC(i2c) && !LL_I2C_IsActiveFlag_TCR(i2c)) {
 		if (check_errors(dev, __func__)) {
 			return -EIO;
 		}
+		if ((k_uptime_get() - start_time) >
+		    STM32_I2C_TRANSFER_TIMEOUT_MSEC) {
+			return -ETIMEDOUT;
+		}
 	}
 	/* Issue stop condition if necessary */
 	if (current_msg_flags & I2C_MSG_STOP) {
 		LL_I2C_GenerateStopCondition(i2c);
 		while (!LL_I2C_IsActiveFlag_STOP(i2c)) {
+			if ((k_uptime_get() - start_time) >
+			    STM32_I2C_TRANSFER_TIMEOUT_MSEC) {
+				return -ETIMEDOUT;
+			}
 		}
 
 		LL_I2C_ClearFlag_STOP(i2c);
@@ -772,6 +781,7 @@
 	I2C_TypeDef *i2c = cfg->i2c;
 	unsigned int len = 0U;
 	uint8_t *buf = msg->buf;
+	int64_t start_time = k_uptime_get();
 
 	msg_init(dev, msg, next_msg_flags, slave, LL_I2C_REQUEST_WRITE);
 
@@ -785,6 +795,11 @@
 			if (check_errors(dev, __func__)) {
 				return -EIO;
 			}
+
+			if ((k_uptime_get() - start_time) >
+			    STM32_I2C_TRANSFER_TIMEOUT_MSEC) {
+				return -ETIMEDOUT;
+			}
 		}
 
 		LL_I2C_TransmitData8(i2c, *buf);
@@ -802,6 +817,7 @@
 	I2C_TypeDef *i2c = cfg->i2c;
 	unsigned int len = 0U;
 	uint8_t *buf = msg->buf;
+	int64_t start_time = k_uptime_get();
 
 	msg_init(dev, msg, next_msg_flags, slave, LL_I2C_REQUEST_READ);
 
@@ -811,6 +827,10 @@
 			if (check_errors(dev, __func__)) {
 				return -EIO;
 			}
+			if ((k_uptime_get() - start_time) >
+			    STM32_I2C_TRANSFER_TIMEOUT_MSEC) {
+				return -ETIMEDOUT;
+			}
 		}
 
 		*buf = LL_I2C_ReceiveData8(i2c);
@@ -1181,5 +1201,26 @@
 		msg.len = rest;
 	} while (rest > 0U);
 
+#ifndef CONFIG_I2C_STM32_INTERRUPT
+	struct i2c_stm32_data *data = dev->data;
+
+	if (ret == -ETIMEDOUT) {
+		if (LL_I2C_IsEnabledReloadMode(i2c)) {
+			LL_I2C_DisableReloadMode(i2c);
+		}
+#if defined(CONFIG_I2C_TARGET)
+		data->master_active = false;
+		if (!data->slave_attached && !data->smbalert_active) {
+			LL_I2C_Disable(i2c);
+		}
+#else
+		if (!data->smbalert_active) {
+			LL_I2C_Disable(i2c);
+		}
+#endif
+		return -EIO;
+	}
+#endif /* !CONFIG_I2C_STM32_INTERRUPT */
+
 	return ret;
 }