Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

i2c: stm32f7: reinit_completion() per transfer not per msg

Currently, the driver may repeatedly call reinit_completion() during
transfer which contains multiple messages, while another thread is
waiting for the completion.

This happens during transfer with more than 1 message, invoked via
stm32f7_i2c_xfer_core() -> stm32f7_i2c_xfer_msg(). After invoking the
stm32f7_i2c_xfer_msg() to start transfer, stm32f7_i2c_xfer_core()
calls wait_for_completion_timeout() to wait for completion of the
transfer of all messages. When the first message transfer completes,
the hard IRQ handler triggers, and detects transfer completion, which
leads to stm32f7_i2c_isr_event_thread() IRQ thread being started. The
stm32f7_i2c_isr_event_thread() calls stm32f7_i2c_xfer_msg() in case
there are more messages.

Without this change, the second and later stm32f7_i2c_xfer_msg() would
call reinit_completion() on the completion which is still being waited
for in stm32f7_i2c_xfer_core(). Fix this by moving the reinit_completion()
into stm32f7_i2c_xfer_core(), together with wait_for_completion_timeout().

Since stm32f7_i2c_xfer_core() now waits for completion of the entire
transfer, increase the default timeout. This fixes sporadic transfer
timeouts on STM32MP25xx during kernel boot.

Fixes: aeb068c57214 ("i2c: i2c-stm32f7: add driver")
Signed-off-by: Marek Vasut <marex@nabladev.com>
[wsa: reworded commit subject]
Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>

authored by

Marek Vasut and committed by
Wolfram Sang
02b7cd68 9a937ca2

+3 -3
+3 -3
drivers/i2c/busses/i2c-stm32f7.c
··· 895 895 f7_msg->result = 0; 896 896 f7_msg->stop = (i2c_dev->msg_id >= i2c_dev->msg_num - 1); 897 897 898 - reinit_completion(&i2c_dev->complete); 899 - 900 898 cr1 = readl_relaxed(base + STM32F7_I2C_CR1); 901 899 cr2 = readl_relaxed(base + STM32F7_I2C_CR2); 902 900 ··· 1726 1728 if (ret) 1727 1729 goto pm_free; 1728 1730 1731 + reinit_completion(&i2c_dev->complete); 1732 + 1729 1733 stm32f7_i2c_xfer_msg(i2c_dev, msgs); 1730 1734 1731 1735 if (!i2c_dev->atomic) ··· 2253 2253 snprintf(adap->name, sizeof(adap->name), "STM32F7 I2C(%pa)", 2254 2254 &res->start); 2255 2255 adap->owner = THIS_MODULE; 2256 - adap->timeout = 2 * HZ; 2256 + adap->timeout = 8 * HZ; 2257 2257 adap->retries = 3; 2258 2258 adap->algo = &stm32f7_i2c_algo; 2259 2259 adap->dev.parent = &pdev->dev;