diff mbox

[v2,2/2] spi/spi-bcm2835: Add bcm2835_spi_transfer_one_message in spi-bcm2835.c

Message ID 91a77832e7d4c5ca5f5ec6f81251922ee8019e77.1519492575.git.meghana.madhyastha@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Meghana Madhyastha Feb. 24, 2018, 6:17 p.m. UTC
Add bcm2835_spi_transfer_one_message in spi-bcm2835.c. This function calls
the helper spi_split_transfers_maxsize before calling spi_transfer_one_message
to split the message into smaller chunks to be able to use dma.

Signed-off-by: Meghana Madhyastha <meghana.madhyastha@gmail.com>
---
 drivers/spi/spi-bcm2835.c | 14 ++++++++++++++
 drivers/spi/spi.c         |  5 ++---
 include/linux/spi/spi.h   |  2 ++
 3 files changed, 18 insertions(+), 3 deletions(-)

Comments

Lukas Wunner Feb. 25, 2018, 4:49 p.m. UTC | #1
On Sat, Feb 24, 2018 at 06:17:12PM +0000, Meghana Madhyastha wrote:
> --- a/drivers/spi/spi.c
> +++ b/drivers/spi/spi.c
> @@ -1003,7 +1003,7 @@ static int spi_map_msg(struct spi_controller *ctlr, struct spi_message *msg)
>   * drivers which implement a transfer_one() operation.  It provides
>   * standard handling of delays and chip select management.
>   */
> -static int spi_transfer_one_message(struct spi_controller *ctlr,
> +int spi_transfer_one_message(struct spi_controller *ctlr,

An alternative to exporting this function would be to have it check
if any of the transfers in the message exceed ctlr->max_dma_len,
and automatically split those.  That's for Mark to decide.


>  		if (xfer->tx_buf || xfer->rx_buf) {
>  			reinit_completion(&ctlr->xfer_completion);
> -

Spurious deleted newline.


>  	/* calculate how many we have to replace */
>  	count = DIV_ROUND_UP(xfer->len, maxsize);
> -

Another one.

Thanks,

Lukas
--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c
index 2fd650891c07..68d35407e7a3 100644
--- a/drivers/spi/spi-bcm2835.c
+++ b/drivers/spi/spi-bcm2835.c
@@ -579,6 +579,19 @@  static int bcm2835_spi_transfer_one(struct spi_master *master,
 	return bcm2835_spi_transfer_one_irq(master, spi, tfr, cs);
 }
 
+static int bcm2835_spi_transfer_one_message(struct spi_controller *ctlr,
+					struct spi_message *msg)
+{
+	int ret;
+	gfp_t gfp_flags = GFP_KERNEL | GFP_DMA;
+	size_t max_transfer_size = 64;
+	ret = spi_split_transfers_maxsize(ctlr, msg, max_transfer_size, gfp_flags);
+	if (ret)
+		return ret;
+
+	return spi_transfer_one_message(ctlr, msg);
+}
+
 static int bcm2835_spi_prepare_message(struct spi_master *master,
 				       struct spi_message *msg)
 {
@@ -739,6 +752,7 @@  static int bcm2835_spi_probe(struct platform_device *pdev)
 	master->setup = bcm2835_spi_setup;
 	master->set_cs = bcm2835_spi_set_cs;
 	master->transfer_one = bcm2835_spi_transfer_one;
+	master->transfer_one_message = bcm2835_spi_transfer_one_message;
 	master->handle_err = bcm2835_spi_handle_err;
 	master->prepare_message = bcm2835_spi_prepare_message;
 	master->dev.of_node = pdev->dev.of_node;
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index b33a727a0158..3a352a0a6cdf 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -1003,7 +1003,7 @@  static int spi_map_msg(struct spi_controller *ctlr, struct spi_message *msg)
  * drivers which implement a transfer_one() operation.  It provides
  * standard handling of delays and chip select management.
  */
-static int spi_transfer_one_message(struct spi_controller *ctlr,
+int spi_transfer_one_message(struct spi_controller *ctlr,
 				    struct spi_message *msg)
 {
 	struct spi_transfer *xfer;
@@ -1026,7 +1026,6 @@  static int spi_transfer_one_message(struct spi_controller *ctlr,
 
 		if (xfer->tx_buf || xfer->rx_buf) {
 			reinit_completion(&ctlr->xfer_completion);
-
 			ret = ctlr->transfer_one(ctlr, msg->spi, xfer);
 			if (ret < 0) {
 				SPI_STATISTICS_INCREMENT_FIELD(statm,
@@ -1111,6 +1110,7 @@  static int spi_transfer_one_message(struct spi_controller *ctlr,
 
 	return ret;
 }
+EXPORT_SYMBOL_GPL(spi_transfer_one_message);
 
 /**
  * spi_finalize_current_transfer - report completion of a transfer
@@ -2583,7 +2583,6 @@  static int __spi_split_transfer_maxsize(struct spi_controller *ctlr,
 
 	/* calculate how many we have to replace */
 	count = DIV_ROUND_UP(xfer->len, maxsize);
-
 	/* create replacement */
 	srt = spi_replace_transfers(msg, xfer, 1, count, NULL, 0, gfp);
 	if (IS_ERR(srt))
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
index bc6bb325d1bf..49b6dbce3e6d 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -622,6 +622,8 @@  extern void spi_finalize_current_transfer(struct spi_controller *ctlr);
 /* the spi driver core manages memory for the spi_controller classdev */
 extern struct spi_controller *__spi_alloc_controller(struct device *host,
 						unsigned int size, bool slave);
+extern int spi_transfer_one_message(struct spi_controller *ctlr,
+						struct spi_message *msg);
 
 static inline struct spi_controller *spi_alloc_master(struct device *host,
 						      unsigned int size)