brcm63xx: backport upstream solution for SPI message size limits
[openwrt/openwrt.git] / target / linux / brcm63xx / patches-4.4 / 000-4.5-20-spi-expose-master-transfer-size-limitation.patch
diff --git a/target/linux/brcm63xx/patches-4.4/000-4.5-20-spi-expose-master-transfer-size-limitation.patch b/target/linux/brcm63xx/patches-4.4/000-4.5-20-spi-expose-master-transfer-size-limitation.patch
new file mode 100644 (file)
index 0000000..21e037c
--- /dev/null
@@ -0,0 +1,51 @@
+From 4acad4aae10d1fa79a075b38b5c73772c44f576c Mon Sep 17 00:00:00 2001
+From: Michal Suchanek <hramrach@gmail.com>
+Date: Wed, 2 Dec 2015 10:38:21 +0000
+Subject: [PATCH] spi: expose master transfer size limitation.
+
+On some SPI controllers it is not feasible to transfer arbitrary amount
+of data at once.
+
+When the limit on transfer size is a few kilobytes at least it makes
+sense to use the SPI hardware rather than reverting to gpio driver.
+
+The protocol drivers need a way to check that they do not sent overly
+long messages, though.
+
+Signed-off-by: Michal Suchanek <hramrach@gmail.com>
+Signed-off-by: Mark Brown <broonie@kernel.org>
+---
+ include/linux/spi/spi.h | 15 +++++++++++++++
+ 1 file changed, 15 insertions(+)
+
+--- a/include/linux/spi/spi.h
++++ b/include/linux/spi/spi.h
+@@ -428,6 +428,12 @@ struct spi_master {
+ #define SPI_MASTER_MUST_RX      BIT(3)                /* requires rx */
+ #define SPI_MASTER_MUST_TX      BIT(4)                /* requires tx */
++      /*
++       * on some hardware transfer size may be constrained
++       * the limit may depend on device transfer settings
++       */
++      size_t (*max_transfer_size)(struct spi_device *spi);
++
+       /* lock and mutex for SPI bus locking */
+       spinlock_t              bus_lock_spinlock;
+       struct mutex            bus_lock_mutex;
+@@ -837,6 +843,15 @@ extern int spi_async(struct spi_device *
+ extern int spi_async_locked(struct spi_device *spi,
+                           struct spi_message *message);
++static inline size_t
++spi_max_transfer_size(struct spi_device *spi)
++{
++      struct spi_master *master = spi->master;
++      if (!master->max_transfer_size)
++              return SIZE_MAX;
++      return master->max_transfer_size(spi);
++}
++
+ /*---------------------------------------------------------------------------*/
+ /* All these synchronous SPI transfer routines are utilities layered