diff options
author | Bastien Curutchet <bastien.curutchet@bootlin.com> | 2024-08-28 08:31:31 +0200 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2024-08-28 13:38:02 +0100 |
commit | 2fe6102bf01a5f4f48f211c2e5c8a274342fccb1 (patch) | |
tree | e3ee95ef5653013ecf71750e89ae57088b3477bc | |
parent | 91232b00b1a5d2486770c72c51a752a77c7601b2 (diff) |
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>
-rw-r--r-- | drivers/spi/spi-davinci.c | 8 |
1 files changed, 7 insertions, 1 deletions
diff --git a/drivers/spi/spi-davinci.c b/drivers/spi/spi-davinci.c index f7e8b5efa50e..ad26c8409733 100644 --- a/drivers/spi/spi-davinci.c +++ b/drivers/spi/spi-davinci.c @@ -570,6 +570,7 @@ static int davinci_spi_bufs(struct spi_device *spi, struct spi_transfer *t) u32 errors = 0; struct davinci_spi_config *spicfg; struct davinci_spi_platform_data *pdata; + unsigned long timeout; dspi = spi_controller_get_devdata(spi->controller); pdata = &dspi->pdata; @@ -661,7 +662,12 @@ static int davinci_spi_bufs(struct spi_device *spi, struct spi_transfer *t) /* Wait for the transfer to complete */ if (spicfg->io_type != SPI_IO_TYPE_POLL) { - if (wait_for_completion_timeout(&dspi->done, HZ) == 0) + timeout = DIV_ROUND_UP(t->speed_hz, MSEC_PER_SEC); + timeout = DIV_ROUND_UP(t->len * 8, timeout); + /* Assume we are at most 2x slower than the nominal bus speed */ + timeout = 2 * msecs_to_jiffies(timeout); + + if (wait_for_completion_timeout(&dspi->done, timeout) == 0) errors = SPIFLG_TIMEOUT_MASK; } else { while (dspi->rcount > 0 || dspi->wcount > 0) { |