diff options
author | Mark Brown <broonie@kernel.org> | 2023-06-23 03:31:11 +0300 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2023-06-23 03:31:11 +0300 |
commit | a77541cab0be8c8a68f70cdeb68359fbe15e4612 (patch) | |
tree | 369476450a9fda7456f764e2be68035f6c8fced8 /include | |
parent | 01fa9edd8bcf1c4fe330ea000c3da9ecf76c76a0 (diff) | |
parent | 6eef895581c9b5fcd002ff77837e0c3a4b1eecf6 (diff) | |
download | linux-a77541cab0be8c8a68f70cdeb68359fbe15e4612.tar.xz |
spi: Helper for deriving timeout values
Merge series from Miquel Raynal <miquel.raynal@bootlin.com>:
I recently came across an issue with the Atmel spi controller driver
which would stop my transfers after a too small timeout when performing
big transfers (reading a 4MiB flash in one transfer). My initial idea
was to derive a the maximum amount of time a transfer would take
depending on its size and use that as value to avoid erroring-out when
not relevant. Mark wanted to go further by creating a core helper doing
that, based on the heuristics from the sun6i driver.
Here is a small series of 3 patches doing exactly that.
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/spi/spi.h | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index cfe42f8cd7a4..32c94eae8926 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -1261,6 +1261,23 @@ static inline bool spi_is_bpw_supported(struct spi_device *spi, u32 bpw) return false; } +/** + * spi_controller_xfer_timeout - Compute a suitable timeout value + * @ctlr: SPI device + * @xfer: Transfer descriptor + * + * Compute a relevant timeout value for the given transfer. We derive the time + * that it would take on a single data line and take twice this amount of time + * with a minimum of 500ms to avoid false positives on loaded systems. + * + * Returns: Transfer timeout value in milliseconds. + */ +static inline unsigned int spi_controller_xfer_timeout(struct spi_controller *ctlr, + struct spi_transfer *xfer) +{ + return max(xfer->len * 8 * 2 / (xfer->speed_hz / 1000), 500U); +} + /*---------------------------------------------------------------------------*/ /* SPI transfer replacement methods which make use of spi_res */ |