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

spi: davinci: Adapt transfer's timeout to transfer's length

The timeout used when waiting for transfer's completion is always set to
HZ. This isn't enough if a transfer is too large or if the bus speed is
too low.

Use the bus speed and the transfer length to calculate an appropriate
timeout

Signed-off-by: Bastien Curutchet <bastien.curutchet@bootlin.com>
Link: https://patch.msgid.link/20240828063131.10507-1-bastien.curutchet@bootlin.com
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Bastien Curutchet and committed by
Mark Brown
2fe6102b 91232b00

+7 -1
+7 -1
drivers/spi/spi-davinci.c
··· 570 570 u32 errors = 0; 571 571 struct davinci_spi_config *spicfg; 572 572 struct davinci_spi_platform_data *pdata; 573 + unsigned long timeout; 573 574 574 575 dspi = spi_controller_get_devdata(spi->controller); 575 576 pdata = &dspi->pdata; ··· 662 661 663 662 /* Wait for the transfer to complete */ 664 663 if (spicfg->io_type != SPI_IO_TYPE_POLL) { 665 - if (wait_for_completion_timeout(&dspi->done, HZ) == 0) 664 + timeout = DIV_ROUND_UP(t->speed_hz, MSEC_PER_SEC); 665 + timeout = DIV_ROUND_UP(t->len * 8, timeout); 666 + /* Assume we are at most 2x slower than the nominal bus speed */ 667 + timeout = 2 * msecs_to_jiffies(timeout); 668 + 669 + if (wait_for_completion_timeout(&dspi->done, timeout) == 0) 666 670 errors = SPIFLG_TIMEOUT_MASK; 667 671 } else { 668 672 while (dspi->rcount > 0 || dspi->wcount > 0) {