diff mbox

[v3,1/2] spi: Split spi message into chunks of <65535 in the spi subsystem

Message ID 648641e37f11ac4a4d94d371e7b676c5a6108edd.1520848302.git.meghana.madhyastha@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Meghana Madhyastha March 12, 2018, 9:54 a.m. UTC
Split spi messages into chunks of <65535 in the spi subsystem and remove the message
length warning in bcm2835_spi_can_dma. This is so that the messages can be transferred
via dma and that the tinydrm drivers need not split it. The current chunk size is 65532.
This is because the scatter gather segment is required to be multiple of 4. The size
has to be <65535 due to hardware limitations.

Signed-off-by: Meghana Madhyastha <meghana.madhyastha@gmail.com>
---
 drivers/spi/spi-bcm2835.c | 22 ++++++++--------------
 1 file changed, 8 insertions(+), 14 deletions(-)

Comments

Eric Anholt March 16, 2018, 11:55 p.m. UTC | #1
Meghana Madhyastha <meghana.madhyastha@gmail.com> writes:

> Split spi messages into chunks of <65535 in the spi subsystem and remove the message
> length warning in bcm2835_spi_can_dma. This is so that the messages can be transferred
> via dma and that the tinydrm drivers need not split it. The current chunk size is 65532.
> This is because the scatter gather segment is required to be multiple of 4. The size
> has to be <65535 due to hardware limitations.
>
> Signed-off-by: Meghana Madhyastha <meghana.madhyastha@gmail.com>
> ---
>  drivers/spi/spi-bcm2835.c | 22 ++++++++--------------
>  1 file changed, 8 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c
> index f35cc10772f6..280ffa5aef7e 100644
> --- a/drivers/spi/spi-bcm2835.c
> +++ b/drivers/spi/spi-bcm2835.c
> @@ -365,19 +365,6 @@ static bool bcm2835_spi_can_dma(struct spi_master *master,
>  	if (tfr->len < BCM2835_SPI_DMA_MIN_LENGTH)
>  		return false;
>  
> -	/* BCM2835_SPI_DLEN has defined a max transfer size as
> -	 * 16 bit, so max is 65535
> -	 * we can revisit this by using an alternative transfer
> -	 * method - ideally this would get done without any more
> -	 * interaction...
> -	 */
> -	if (tfr->len > 65535) {
> -		dev_warn_once(&spi->dev,
> -			      "transfer size of %d too big for dma-transfer\n",
> -			      tfr->len);
> -		return false;
> -	}
> -
>  	/* if we run rx/tx_buf with word aligned addresses then we are OK */
>  	if ((((size_t)tfr->rx_buf & 3) == 0) &&
>  	    (((size_t)tfr->tx_buf & 3) == 0))
> @@ -461,7 +448,7 @@ static void bcm2835_dma_init(struct spi_master *master, struct device *dev)
>  
>  	/* all went well, so set can_dma */
>  	master->can_dma = bcm2835_spi_can_dma;
> -	master->max_dma_len = 65535; /* limitation by BCM2835_SPI_DLEN */
> +	master->max_dma_len = 65532; /* limitation by BCM2835_SPI_DLEN */
>  	/* need to do TX AND RX DMA, so we need dummy buffers */
>  	master->flags = SPI_MASTER_MUST_RX | SPI_MASTER_MUST_TX;
>  
> @@ -597,7 +584,14 @@ static int bcm2835_spi_prepare_message(struct spi_master *master,
>  {
>  	struct spi_device *spi = msg->spi;
>  	struct bcm2835_spi *bs = spi_master_get_devdata(master);
> +	gfp_t gfp_flags = GFP_KERNEL | GFP_DMA;
>  	u32 cs = bcm2835_rd(bs, BCM2835_SPI_CS);
> +	size_t max_transfer_size = 65532;
> +	int ret;
> +
> +	ret = spi_split_transfers_maxsize(master, msg, max_transfer_size, gfp_flags);
> +	if (ret)
> +	       return ret;

Mark: is this how spi_split_transfers_maxsize() is supposed to be used?
If so, I'm happy to see our hardware have fewer limitations, and it gets
my:

Reviewed-by: Eric Anholt <eric@anholt.net>
diff mbox

Patch

diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c
index f35cc10772f6..280ffa5aef7e 100644
--- a/drivers/spi/spi-bcm2835.c
+++ b/drivers/spi/spi-bcm2835.c
@@ -365,19 +365,6 @@  static bool bcm2835_spi_can_dma(struct spi_master *master,
 	if (tfr->len < BCM2835_SPI_DMA_MIN_LENGTH)
 		return false;
 
-	/* BCM2835_SPI_DLEN has defined a max transfer size as
-	 * 16 bit, so max is 65535
-	 * we can revisit this by using an alternative transfer
-	 * method - ideally this would get done without any more
-	 * interaction...
-	 */
-	if (tfr->len > 65535) {
-		dev_warn_once(&spi->dev,
-			      "transfer size of %d too big for dma-transfer\n",
-			      tfr->len);
-		return false;
-	}
-
 	/* if we run rx/tx_buf with word aligned addresses then we are OK */
 	if ((((size_t)tfr->rx_buf & 3) == 0) &&
 	    (((size_t)tfr->tx_buf & 3) == 0))
@@ -461,7 +448,7 @@  static void bcm2835_dma_init(struct spi_master *master, struct device *dev)
 
 	/* all went well, so set can_dma */
 	master->can_dma = bcm2835_spi_can_dma;
-	master->max_dma_len = 65535; /* limitation by BCM2835_SPI_DLEN */
+	master->max_dma_len = 65532; /* limitation by BCM2835_SPI_DLEN */
 	/* need to do TX AND RX DMA, so we need dummy buffers */
 	master->flags = SPI_MASTER_MUST_RX | SPI_MASTER_MUST_TX;
 
@@ -597,7 +584,14 @@  static int bcm2835_spi_prepare_message(struct spi_master *master,
 {
 	struct spi_device *spi = msg->spi;
 	struct bcm2835_spi *bs = spi_master_get_devdata(master);
+	gfp_t gfp_flags = GFP_KERNEL | GFP_DMA;
 	u32 cs = bcm2835_rd(bs, BCM2835_SPI_CS);
+	size_t max_transfer_size = 65532;
+	int ret;
+
+	ret = spi_split_transfers_maxsize(master, msg, max_transfer_size, gfp_flags);
+	if (ret)
+	       return ret;
 
 	cs &= ~(BCM2835_SPI_CS_CPOL | BCM2835_SPI_CS_CPHA);