[PATCH 3/4] spi: add flags SPI_MASTER_MUST_*_SG to api

kernel at martin.sperl.org kernel at martin.sperl.org
Mon May 25 05:44:25 PDT 2015


From: Martin Sperl <kernel at martin.sperl.org>

This avoid unnecessary mapping of null pages in sg_lists for masters
that do not need a sg_list when rx_buf/tx_buff == NULL avoid.

Only spi-masters that require a mapped scatter-gather map need to set
this, but they would not need to set SPI_MASTER_MUST_RX/TX.

Signed-off-by: Martin Sperl <kernel at martin.sperl.org>
---
 drivers/spi/spi.c       |   38 +++++++++++++++++++-------------------
 include/linux/spi/spi.h |    2 ++
 2 files changed, 21 insertions(+), 19 deletions(-)

Note that this is an optional patch to avoid the overhead
for spi_masters that do not need the dummy-page functionality.

diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 7e1a12c..9205928 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -570,25 +570,25 @@ static int __spi_map_msg(struct spi_master *master, struct spi_message *msg)
 		if (!master->can_dma(master, msg->spi, xfer))
 			continue;
 
-		/* potentially add a flag to spi_master
-		 * (SPI_MASTER_MUST_TX_SG) to avoid unnecessary mapping
-		 */
-		ret = spi_map_buf(master, tx_dev, &xfer->tx_sg,
-				  (void *)xfer->tx_buf, xfer->len,
-				  DMA_TO_DEVICE);
-		if (ret != 0)
-			return ret;
-
-		/* potentially add a flag to spi_master
-		 * (SPI_MASTER_MUST_RX_SG) to avoid unnecessary mapping
-		 */
-		ret = spi_map_buf(master, rx_dev, &xfer->rx_sg,
-				  xfer->rx_buf, xfer->len,
-				  DMA_FROM_DEVICE);
-		if (ret != 0) {
-			spi_unmap_buf(master, tx_dev, &xfer->tx_sg,
-				      DMA_TO_DEVICE);
-			return ret;
+		if (xfer->tx_buf ||
+		    (master->flags & SPI_MASTER_MUST_TX_SG)) {
+			ret = spi_map_buf(master, tx_dev, &xfer->tx_sg,
+					  (void *)xfer->tx_buf, xfer->len,
+					  DMA_TO_DEVICE);
+			if (ret != 0)
+				return ret;
+		}
+
+		if (xfer->rx_buf ||
+		    (master->flags & SPI_MASTER_MUST_RX_SG)) {
+			ret = spi_map_buf(master, rx_dev, &xfer->rx_sg,
+					  xfer->rx_buf, xfer->len,
+					  DMA_FROM_DEVICE);
+			if (ret != 0) {
+				spi_unmap_buf(master, tx_dev, &xfer->tx_sg,
+					      DMA_TO_DEVICE);
+				return ret;
+			}
 		}
 	}
 
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
index 9ffa506..8b70419 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -357,6 +357,8 @@ struct spi_master {
 #define SPI_MASTER_NO_TX	BIT(2)		/* can't do buffer write */
 #define SPI_MASTER_MUST_RX      BIT(3)		/* requires rx */
 #define SPI_MASTER_MUST_TX      BIT(4)		/* requires tx */
+#define SPI_MASTER_MUST_RX_SG   BIT(5)		/* requires rx sg_list */
+#define SPI_MASTER_MUST_TX_SG   BIT(6)		/* requires tx sg_list */
 
 	/* lock and mutex for SPI bus locking */
 	spinlock_t		bus_lock_spinlock;
-- 
1.7.10.4




More information about the linux-rpi-kernel mailing list