summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2023-06-23 03:31:11 +0300
committerMark Brown <broonie@kernel.org>2023-06-23 03:31:11 +0300
commita77541cab0be8c8a68f70cdeb68359fbe15e4612 (patch)
tree369476450a9fda7456f764e2be68035f6c8fced8 /include
parent01fa9edd8bcf1c4fe330ea000c3da9ecf76c76a0 (diff)
parent6eef895581c9b5fcd002ff77837e0c3a4b1eecf6 (diff)
downloadlinux-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.h17
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 */