linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC] [PATCH 0/3] scatterlist: Add support to clone sg_table
@ 2016-06-17 22:45 Franklin S Cooper Jr
  2016-06-17 22:45 ` [RFC] [PATCH 1/3] lib/scatterlist: " Franklin S Cooper Jr
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Franklin S Cooper Jr @ 2016-06-17 22:45 UTC (permalink / raw)
  To: broonie, linux-kernel, linux-spi, david.s.gordon, akpm, nsekhar,
	vigneshr, peter.ujfalusi
  Cc: Franklin S Cooper Jr

This patchset creates two new functions within scatterlist that allows a
user to pass in a sg_table and receive a duplicate copy. The sgl in this
copied table are dynamically allocated but its values such as offset,
length and dma_address are the same as its variant within the sgl in the
original sg_table.

This is useful when tweaks to sgl may be needed to alter a future DMA
operation by tweaking the table nents count or the individual sgl
offset/length without changing the original values.

An example use case is also included in this patchset. In the omap2-mcspi
driver on certain OMAP SOCs if certain conditions are met the DMA should
transfer one or two less elements when reading from the SPI. The
remaining bytes are read in CPU mode. To accomplish this the spi's rx_sg
sgl should have the last entry length reduced for the DMA operation.
However, this change should only be done locally so instead of altering
the original sgl this new function allows a clone to be created.

Franklin S Cooper Jr (3):
  lib/scatterlist: Add support to clone sg_table
  spi: omap2-mcspi: Add comments for RX only DMA buffer workaround
  spi: omap2-mcspi: Use the SPI framework to handle DMA mapping

 drivers/spi/spi-omap2-mcspi.c | 122 +++++++++++++++++-------------------------
 include/linux/scatterlist.h   |   2 +
 lib/scatterlist.c             |  93 ++++++++++++++++++++++++++++++++
 3 files changed, 144 insertions(+), 73 deletions(-)

-- 
1.9.1

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [RFC] [PATCH 1/3] lib/scatterlist: Add support to clone sg_table
  2016-06-17 22:45 [RFC] [PATCH 0/3] scatterlist: Add support to clone sg_table Franklin S Cooper Jr
@ 2016-06-17 22:45 ` Franklin S Cooper Jr
  2016-06-22 15:18   ` Mark Brown
  2016-06-17 22:45 ` [RFC] [PATCH 2/3] spi: omap2-mcspi: Add comments for RX only DMA buffer workaround Franklin S Cooper Jr
  2016-06-17 22:45 ` [RFC] [PATCH 3/3] spi: omap2-mcspi: Use the SPI framework to handle DMA mapping Franklin S Cooper Jr
  2 siblings, 1 reply; 6+ messages in thread
From: Franklin S Cooper Jr @ 2016-06-17 22:45 UTC (permalink / raw)
  To: broonie, linux-kernel, linux-spi, david.s.gordon, akpm, nsekhar,
	vigneshr, peter.ujfalusi
  Cc: Franklin S Cooper Jr

Occasionally there are times you need to tweak a S/G table while
maintaining the original table. This function will duplicate the passed
in S/G table along with its chained sgl and return a pointer to the cloned
copy.

The function also supports passing in a length that can be equal or less
than the original chained S/G list length. This can reduce the length of
the chained S/G list.

Signed-off-by: Franklin S Cooper Jr <fcooper@ti.com>
---
 include/linux/scatterlist.h |  2 +
 lib/scatterlist.c           | 93 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 95 insertions(+)

diff --git a/include/linux/scatterlist.h b/include/linux/scatterlist.h
index cb3c8fe..9a109da 100644
--- a/include/linux/scatterlist.h
+++ b/include/linux/scatterlist.h
@@ -247,6 +247,8 @@ struct scatterlist *sg_next(struct scatterlist *);
 struct scatterlist *sg_last(struct scatterlist *s, unsigned int);
 void sg_init_table(struct scatterlist *, unsigned int);
 void sg_init_one(struct scatterlist *, const void *, unsigned int);
+struct sg_table *sg_table_clone(struct sg_table *orig_table, u64 len,
+				gfp_t gfp_mask);
 int sg_split(struct scatterlist *in, const int in_mapped_nents,
 	     const off_t skip, const int nb_splits,
 	     const size_t *split_sizes,
diff --git a/lib/scatterlist.c b/lib/scatterlist.c
index 004fc70..15a0142 100644
--- a/lib/scatterlist.c
+++ b/lib/scatterlist.c
@@ -180,6 +180,99 @@ static struct scatterlist *sg_kmalloc(unsigned int nents, gfp_t gfp_mask)
 		return kmalloc(nents * sizeof(struct scatterlist), gfp_mask);
 }
 
+/*
+ * sg_clone -	Duplicate an existing chained sgl
+ * @orig_sgl:	Original sg list to be duplicated
+ * @len:	Total length of sg while taking chaining into account
+ * @gfp_mask:	GFP allocation mask
+ *
+ * Description:
+ *   Clone a chained sgl. This cloned copy may be modified in some ways while
+ *   keeping the original sgl in tact. Also allow the cloned copy to have
+ *   a smaller length than the original which may reduce the sgl total
+ *   sg entries.
+ *
+ * Returns:
+ *   Pointer to new kmalloced sg list, ERR_PTR() on error
+ *
+ */
+static struct scatterlist *sg_clone(struct scatterlist *orig_sgl, u64 len,
+				    gfp_t gfp_mask)
+{
+	unsigned int		nents;
+	unsigned long		page_link;
+	struct scatterlist	*sgl, *head;
+
+	nents = sg_nents_for_len(orig_sgl, len);
+
+	if (nents < 0)
+		return ERR_PTR(-EINVAL);
+
+	head = sg_kmalloc(nents, gfp_mask);
+
+	if (!head)
+		return ERR_PTR(-ENOMEM);
+
+	sgl = head;
+
+	sg_init_table(sgl, nents);
+
+	for (; sgl; orig_sgl = sg_next(orig_sgl), sgl = sg_next(sgl)) {
+
+		page_link = sgl->page_link;
+
+		*sgl = *orig_sgl;
+
+		sgl->page_link = page_link;
+
+		if (sg_is_last(sgl))
+			sg_dma_len(sgl) = len;
+		else
+			len -= sg_dma_len(sgl);
+	}
+
+	return head;
+}
+
+/*
+ * sg_table_clone - Duplicate an existing sg_table including chained sgl
+ * @orig_table:     Original sg_table to be duplicated
+ * @len:            Total length of sg while taking chaining into account
+ * @gfp_mask:       GFP allocation mask
+ *
+ * Description:
+ *   Clone a sg_table along with chained sgl. This cloned copy may be
+ *   modified in some ways while keeping the original table and sgl in tact.
+ *   Also allow the cloned sgl copy to have a smaller length than the original
+ *   which may reduce the sgl total sg entries.
+ *
+ * Returns:
+ *   Pointer to new kmalloced sg_table, ERR_PTR() on error
+ *
+ */
+struct sg_table *sg_table_clone(struct sg_table *orig_table, u64 len,
+				gfp_t gfp_mask)
+{
+	struct sg_table	*table;
+
+	table = kmalloc(sizeof(struct sg_table),gfp_mask);
+
+	if (!table)
+		return ERR_PTR(-ENOMEM);
+
+	table->sgl = sg_clone(orig_table->sgl,len,gfp_mask);
+
+	if (IS_ERR(table->sgl)) {
+		kfree(table);
+		return ERR_PTR(-ENOMEM);
+	}
+
+	table->nents = table->orig_nents = sg_nents(table->sgl);
+
+	return table;
+}
+EXPORT_SYMBOL(sg_table_clone);
+
 static void sg_kfree(struct scatterlist *sg, unsigned int nents)
 {
 	if (nents == SG_MAX_SINGLE_ALLOC) {
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [RFC] [PATCH 2/3] spi: omap2-mcspi: Add comments for RX only DMA buffer workaround
  2016-06-17 22:45 [RFC] [PATCH 0/3] scatterlist: Add support to clone sg_table Franklin S Cooper Jr
  2016-06-17 22:45 ` [RFC] [PATCH 1/3] lib/scatterlist: " Franklin S Cooper Jr
@ 2016-06-17 22:45 ` Franklin S Cooper Jr
  2016-07-05 14:50   ` Applied "spi: omap2-mcspi: Add comments for RX only DMA buffer workaround" to the spi tree Mark Brown
  2016-06-17 22:45 ` [RFC] [PATCH 3/3] spi: omap2-mcspi: Use the SPI framework to handle DMA mapping Franklin S Cooper Jr
  2 siblings, 1 reply; 6+ messages in thread
From: Franklin S Cooper Jr @ 2016-06-17 22:45 UTC (permalink / raw)
  To: broonie, linux-kernel, linux-spi, david.s.gordon, akpm, nsekhar,
	vigneshr, peter.ujfalusi
  Cc: Franklin S Cooper Jr

OMAP35x and OMAP37x mentions in the McSPI End-of-Transfer Sequences section
that if the McSPI is configured as a Master and only DMA RX is being
performed then the DMA transfer size needs to be reduced by 1 or 2.

This was originally implemented by:
commit 57c5c28dbc83 ("spi: omap2_mcspi rxdma bugfix")

This patch adds comments to clarify what is going on in the code since its
not obvious what problem its addressing.

Signed-off-by: Franklin S Cooper Jr <fcooper@ti.com>
---
 drivers/spi/spi-omap2-mcspi.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c
index 1d237e9..c47f958 100644
--- a/drivers/spi/spi-omap2-mcspi.c
+++ b/drivers/spi/spi-omap2-mcspi.c
@@ -459,6 +459,11 @@ omap2_mcspi_rx_dma(struct spi_device *spi, struct spi_transfer *xfer,
 	count = xfer->len;
 	dma_count = xfer->len;
 
+	/*
+	 *  In the "End-of-Transfer Procedure" section for DMA RX in OMAP35x TRM
+	 *  it mentions reducing DMA transfer length by one element in master
+	 *  normal mode.
+	 */
 	if (mcspi->fifo_depth == 0)
 		dma_count -= es;
 
@@ -478,6 +483,10 @@ omap2_mcspi_rx_dma(struct spi_device *spi, struct spi_transfer *xfer,
 
 		dmaengine_slave_config(mcspi_dma->dma_rx, &cfg);
 
+		/*
+		 *  Reduce DMA transfer length by one more if McSPI is
+		 *  configured in turbo mode.
+		 */
 		if ((l & OMAP2_MCSPI_CHCONF_TURBO) && mcspi->fifo_depth == 0)
 			dma_count -= es;
 
@@ -507,6 +516,10 @@ omap2_mcspi_rx_dma(struct spi_device *spi, struct spi_transfer *xfer,
 	if (mcspi->fifo_depth > 0)
 		return count;
 
+	/*
+	 *  Due to the DMA transfer length reduction the missing bytes must
+	 *  be read manually to receive all of the expected data.
+	 */
 	omap2_mcspi_set_enable(spi, 0);
 
 	elements = element_count - 1;
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [RFC] [PATCH 3/3] spi: omap2-mcspi: Use the SPI framework to handle DMA mapping
  2016-06-17 22:45 [RFC] [PATCH 0/3] scatterlist: Add support to clone sg_table Franklin S Cooper Jr
  2016-06-17 22:45 ` [RFC] [PATCH 1/3] lib/scatterlist: " Franklin S Cooper Jr
  2016-06-17 22:45 ` [RFC] [PATCH 2/3] spi: omap2-mcspi: Add comments for RX only DMA buffer workaround Franklin S Cooper Jr
@ 2016-06-17 22:45 ` Franklin S Cooper Jr
  2 siblings, 0 replies; 6+ messages in thread
From: Franklin S Cooper Jr @ 2016-06-17 22:45 UTC (permalink / raw)
  To: broonie, linux-kernel, linux-spi, david.s.gordon, akpm, nsekhar,
	vigneshr, peter.ujfalusi
  Cc: Franklin S Cooper Jr

Currently, the driver handles mapping buffers to be used by the DMA.
However, there are times that the current mapping implementation will
fail for certain buffers. Fortunately, the SPI framework can detect
and map buffers so its usable by the DMA.

Update the driver to utilize the SPI framework for buffer
mapping instead. Also incorporate hooks that the framework uses to
determine if the DMA can or can not be used.

This will result in the original omap2_mcspi_transfer_one function being
deleted and omap2_mcspi_work_one being renamed to
omap2_mcspi_transfer_one. Previously transfer_one was only responsible
for mapping and work_one handled the transfer. But now only transferring
needs to be handled by the driver.

Signed-off-by: Franklin S Cooper Jr <fcooper@ti.com>
---
 drivers/spi/spi-omap2-mcspi.c | 109 ++++++++++++++----------------------------
 1 file changed, 36 insertions(+), 73 deletions(-)

diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c
index c47f958..84ba671 100644
--- a/drivers/spi/spi-omap2-mcspi.c
+++ b/drivers/spi/spi-omap2-mcspi.c
@@ -419,16 +419,13 @@ static void omap2_mcspi_tx_dma(struct spi_device *spi,
 
 	if (mcspi_dma->dma_tx) {
 		struct dma_async_tx_descriptor *tx;
-		struct scatterlist sg;
 
 		dmaengine_slave_config(mcspi_dma->dma_tx, &cfg);
 
-		sg_init_table(&sg, 1);
-		sg_dma_address(&sg) = xfer->tx_dma;
-		sg_dma_len(&sg) = xfer->len;
-
-		tx = dmaengine_prep_slave_sg(mcspi_dma->dma_tx, &sg, 1,
-		DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+		tx = dmaengine_prep_slave_sg(mcspi_dma->dma_tx, xfer->tx_sg.sgl,
+					     xfer->tx_sg.nents,
+					     DMA_MEM_TO_DEV,
+					     DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
 		if (tx) {
 			tx->callback = omap2_mcspi_tx_callback;
 			tx->callback_param = spi;
@@ -449,7 +446,8 @@ omap2_mcspi_rx_dma(struct spi_device *spi, struct spi_transfer *xfer,
 {
 	struct omap2_mcspi	*mcspi;
 	struct omap2_mcspi_dma  *mcspi_dma;
-	unsigned int		count, dma_count;
+	struct sg_table		*cloned_table = NULL;
+	unsigned int		count, transfer_reduction = 0;
 	u32			l;
 	int			elements = 0;
 	int			word_len, element_count;
@@ -457,7 +455,6 @@ omap2_mcspi_rx_dma(struct spi_device *spi, struct spi_transfer *xfer,
 	mcspi = spi_master_get_devdata(spi->master);
 	mcspi_dma = &mcspi->dma_channels[spi->chip_select];
 	count = xfer->len;
-	dma_count = xfer->len;
 
 	/*
 	 *  In the "End-of-Transfer Procedure" section for DMA RX in OMAP35x TRM
@@ -465,7 +462,7 @@ omap2_mcspi_rx_dma(struct spi_device *spi, struct spi_transfer *xfer,
 	 *  normal mode.
 	 */
 	if (mcspi->fifo_depth == 0)
-		dma_count -= es;
+		transfer_reduction = es;
 
 	word_len = cs->word_len;
 	l = mcspi_cached_chconf0(spi);
@@ -479,7 +476,6 @@ omap2_mcspi_rx_dma(struct spi_device *spi, struct spi_transfer *xfer,
 
 	if (mcspi_dma->dma_rx) {
 		struct dma_async_tx_descriptor *tx;
-		struct scatterlist sg;
 
 		dmaengine_slave_config(mcspi_dma->dma_rx, &cfg);
 
@@ -488,13 +484,22 @@ omap2_mcspi_rx_dma(struct spi_device *spi, struct spi_transfer *xfer,
 		 *  configured in turbo mode.
 		 */
 		if ((l & OMAP2_MCSPI_CHCONF_TURBO) && mcspi->fifo_depth == 0)
-			dma_count -= es;
+			transfer_reduction += es;
+
+		/*
+		 * Get a cloned copy of the rx sg_table whose transfer count
+		 * has been reduced by transfer_reduction.
+		 */
+		cloned_table = sg_table_clone(&xfer->rx_sg,
+					      count - transfer_reduction,
+					      GFP_KERNEL);
 
-		sg_init_table(&sg, 1);
-		sg_dma_address(&sg) = xfer->rx_dma;
-		sg_dma_len(&sg) = dma_count;
+		if (IS_ERR(cloned_table))
+			return 0;
 
-		tx = dmaengine_prep_slave_sg(mcspi_dma->dma_rx, &sg, 1,
+		tx = dmaengine_prep_slave_sg(mcspi_dma->dma_rx,
+				cloned_table->sgl,
+				cloned_table->nents,
 				DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT |
 				DMA_CTRL_ACK);
 		if (tx) {
@@ -510,8 +515,9 @@ omap2_mcspi_rx_dma(struct spi_device *spi, struct spi_transfer *xfer,
 	omap2_mcspi_set_dma_req(spi, 1, 1);
 
 	wait_for_completion(&mcspi_dma->dma_rx_completion);
-	dma_unmap_single(mcspi->dev, xfer->rx_dma, count,
-			 DMA_FROM_DEVICE);
+
+	kfree(cloned_table->sgl);
+	kfree(cloned_table);
 
 	if (mcspi->fifo_depth > 0)
 		return count;
@@ -628,8 +634,6 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer)
 
 	if (tx != NULL) {
 		wait_for_completion(&mcspi_dma->dma_tx_completion);
-		dma_unmap_single(mcspi->dev, xfer->tx_dma, xfer->len,
-				 DMA_TO_DEVICE);
 
 		if (mcspi->fifo_depth > 0) {
 			irqstat_reg = mcspi->base + OMAP2_MCSPI_IRQSTATUS;
@@ -1087,7 +1091,7 @@ static void omap2_mcspi_cleanup(struct spi_device *spi)
 		gpio_free(spi->cs_gpio);
 }
 
-static int omap2_mcspi_work_one(struct omap2_mcspi *mcspi,
+static int omap2_mcspi_transfer_one(struct spi_master *master,
 		struct spi_device *spi, struct spi_transfer *t)
 {
 
@@ -1098,7 +1102,7 @@ static int omap2_mcspi_work_one(struct omap2_mcspi *mcspi,
 	 * chipselect with the FORCE bit ... CS != channel enable.
 	 */
 
-	struct spi_master		*master;
+	struct omap2_mcspi		*mcspi;
 	struct omap2_mcspi_dma		*mcspi_dma;
 	struct omap2_mcspi_cs		*cs;
 	struct omap2_mcspi_device_config *cd;
@@ -1106,7 +1110,7 @@ static int omap2_mcspi_work_one(struct omap2_mcspi *mcspi,
 	int				status = 0;
 	u32				chconf;
 
-	master = spi->master;
+	mcspi = spi_master_get_devdata(master);
 	mcspi_dma = mcspi->dma_channels + spi->chip_select;
 	cs = spi->controller_state;
 	cd = spi->controller_data;
@@ -1166,7 +1170,8 @@ static int omap2_mcspi_work_one(struct omap2_mcspi *mcspi,
 		unsigned	count;
 
 		if ((mcspi_dma->dma_rx && mcspi_dma->dma_tx) &&
-		    (t->len >= DMA_MIN_BYTES))
+		    master->cur_msg_mapped &&
+		    master->can_dma(master, spi, t))
 			omap2_mcspi_set_fifo(spi, t, 1);
 
 		omap2_mcspi_set_enable(spi, 1);
@@ -1177,7 +1182,8 @@ static int omap2_mcspi_work_one(struct omap2_mcspi *mcspi,
 					+ OMAP2_MCSPI_TX0);
 
 		if ((mcspi_dma->dma_rx && mcspi_dma->dma_tx) &&
-		    (t->len >= DMA_MIN_BYTES))
+		    master->cur_msg_mapped &&
+		    master->can_dma(master, spi, t))
 			count = omap2_mcspi_txrx_dma(spi, t);
 		else
 			count = omap2_mcspi_txrx_pio(spi, t);
@@ -1246,55 +1252,11 @@ static int omap2_mcspi_prepare_message(struct spi_master *master,
 	return 0;
 }
 
-static int omap2_mcspi_transfer_one(struct spi_master *master,
-		struct spi_device *spi, struct spi_transfer *t)
+static bool omap2_mcspi_can_dma(struct spi_master *master,
+				struct spi_device *spi,
+				struct spi_transfer *xfer)
 {
-	struct omap2_mcspi	*mcspi;
-	struct omap2_mcspi_dma	*mcspi_dma;
-	const void	*tx_buf = t->tx_buf;
-	void		*rx_buf = t->rx_buf;
-	unsigned	len = t->len;
-
-	mcspi = spi_master_get_devdata(master);
-	mcspi_dma = mcspi->dma_channels + spi->chip_select;
-
-	if ((len && !(rx_buf || tx_buf))) {
-		dev_dbg(mcspi->dev, "transfer: %d Hz, %d %s%s, %d bpw\n",
-				t->speed_hz,
-				len,
-				tx_buf ? "tx" : "",
-				rx_buf ? "rx" : "",
-				t->bits_per_word);
-		return -EINVAL;
-	}
-
-	if (len < DMA_MIN_BYTES)
-		goto skip_dma_map;
-
-	if (mcspi_dma->dma_tx && tx_buf != NULL) {
-		t->tx_dma = dma_map_single(mcspi->dev, (void *) tx_buf,
-				len, DMA_TO_DEVICE);
-		if (dma_mapping_error(mcspi->dev, t->tx_dma)) {
-			dev_dbg(mcspi->dev, "dma %cX %d bytes error\n",
-					'T', len);
-			return -EINVAL;
-		}
-	}
-	if (mcspi_dma->dma_rx && rx_buf != NULL) {
-		t->rx_dma = dma_map_single(mcspi->dev, rx_buf, t->len,
-				DMA_FROM_DEVICE);
-		if (dma_mapping_error(mcspi->dev, t->rx_dma)) {
-			dev_dbg(mcspi->dev, "dma %cX %d bytes error\n",
-					'R', len);
-			if (tx_buf != NULL)
-				dma_unmap_single(mcspi->dev, t->tx_dma,
-						len, DMA_TO_DEVICE);
-			return -EINVAL;
-		}
-	}
-
-skip_dma_map:
-	return omap2_mcspi_work_one(mcspi, spi, t);
+	return (xfer->len >= DMA_MIN_BYTES);
 }
 
 static int omap2_mcspi_master_setup(struct omap2_mcspi *mcspi)
@@ -1374,6 +1336,7 @@ static int omap2_mcspi_probe(struct platform_device *pdev)
 	master->setup = omap2_mcspi_setup;
 	master->auto_runtime_pm = true;
 	master->prepare_message = omap2_mcspi_prepare_message;
+	master->can_dma = omap2_mcspi_can_dma;
 	master->transfer_one = omap2_mcspi_transfer_one;
 	master->set_cs = omap2_mcspi_set_cs;
 	master->cleanup = omap2_mcspi_cleanup;
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [RFC] [PATCH 1/3] lib/scatterlist: Add support to clone sg_table
  2016-06-17 22:45 ` [RFC] [PATCH 1/3] lib/scatterlist: " Franklin S Cooper Jr
@ 2016-06-22 15:18   ` Mark Brown
  0 siblings, 0 replies; 6+ messages in thread
From: Mark Brown @ 2016-06-22 15:18 UTC (permalink / raw)
  To: Franklin S Cooper Jr
  Cc: linux-kernel, linux-spi, david.s.gordon, akpm, nsekhar, vigneshr,
	peter.ujfalusi

[-- Attachment #1: Type: text/plain, Size: 533 bytes --]

On Fri, Jun 17, 2016 at 05:45:11PM -0500, Franklin S Cooper Jr wrote:
> Occasionally there are times you need to tweak a S/G table while
> maintaining the original table. This function will duplicate the passed
> in S/G table along with its chained sgl and return a pointer to the cloned
> copy.

You ought to send this to whoever looks after the scatterlist code as
well, or at least a wider circulation.  Unfortunately that doesn't look
100% clear...  off the top of my head Jens Axboe and Andrew Morton look
like good candidates.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Applied "spi: omap2-mcspi: Add comments for RX only DMA buffer workaround" to the spi tree
  2016-06-17 22:45 ` [RFC] [PATCH 2/3] spi: omap2-mcspi: Add comments for RX only DMA buffer workaround Franklin S Cooper Jr
@ 2016-07-05 14:50   ` Mark Brown
  0 siblings, 0 replies; 6+ messages in thread
From: Mark Brown @ 2016-07-05 14:50 UTC (permalink / raw)
  To: Franklin S Cooper Jr
  Cc: Mark Brown, broonie, linux-kernel, linux-spi, david.s.gordon,
	akpm, nsekhar, vigneshr, peter.ujfalusi, linux-spi

The patch

   spi: omap2-mcspi: Add comments for RX only DMA buffer workaround

has been applied to the spi tree at

   git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git 

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

>From 4bd00413cde851d84b297c1b0dae15109025e84b Mon Sep 17 00:00:00 2001
From: Franklin S Cooper Jr <fcooper@ti.com>
Date: Mon, 27 Jun 2016 09:54:08 -0500
Subject: [PATCH] spi: omap2-mcspi: Add comments for RX only DMA buffer
 workaround

OMAP35x and OMAP37x mentions in the McSPI End-of-Transfer Sequences section
that if the McSPI is configured as a Master and only DMA RX is being
performed then the DMA transfer size needs to be reduced by 1 or 2.

This was originally implemented by:
commit 57c5c28dbc83 ("spi: omap2_mcspi rxdma bugfix")

This patch adds comments to clarify what is going on in the code since its
not obvious what problem its addressing.

Signed-off-by: Franklin S Cooper Jr <fcooper@ti.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
 drivers/spi/spi-omap2-mcspi.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c
index 1d237e93a289..c47f95879833 100644
--- a/drivers/spi/spi-omap2-mcspi.c
+++ b/drivers/spi/spi-omap2-mcspi.c
@@ -459,6 +459,11 @@ omap2_mcspi_rx_dma(struct spi_device *spi, struct spi_transfer *xfer,
 	count = xfer->len;
 	dma_count = xfer->len;
 
+	/*
+	 *  In the "End-of-Transfer Procedure" section for DMA RX in OMAP35x TRM
+	 *  it mentions reducing DMA transfer length by one element in master
+	 *  normal mode.
+	 */
 	if (mcspi->fifo_depth == 0)
 		dma_count -= es;
 
@@ -478,6 +483,10 @@ omap2_mcspi_rx_dma(struct spi_device *spi, struct spi_transfer *xfer,
 
 		dmaengine_slave_config(mcspi_dma->dma_rx, &cfg);
 
+		/*
+		 *  Reduce DMA transfer length by one more if McSPI is
+		 *  configured in turbo mode.
+		 */
 		if ((l & OMAP2_MCSPI_CHCONF_TURBO) && mcspi->fifo_depth == 0)
 			dma_count -= es;
 
@@ -507,6 +516,10 @@ omap2_mcspi_rx_dma(struct spi_device *spi, struct spi_transfer *xfer,
 	if (mcspi->fifo_depth > 0)
 		return count;
 
+	/*
+	 *  Due to the DMA transfer length reduction the missing bytes must
+	 *  be read manually to receive all of the expected data.
+	 */
 	omap2_mcspi_set_enable(spi, 0);
 
 	elements = element_count - 1;
-- 
2.8.1

^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2016-07-05 14:51 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-06-17 22:45 [RFC] [PATCH 0/3] scatterlist: Add support to clone sg_table Franklin S Cooper Jr
2016-06-17 22:45 ` [RFC] [PATCH 1/3] lib/scatterlist: " Franklin S Cooper Jr
2016-06-22 15:18   ` Mark Brown
2016-06-17 22:45 ` [RFC] [PATCH 2/3] spi: omap2-mcspi: Add comments for RX only DMA buffer workaround Franklin S Cooper Jr
2016-07-05 14:50   ` Applied "spi: omap2-mcspi: Add comments for RX only DMA buffer workaround" to the spi tree Mark Brown
2016-06-17 22:45 ` [RFC] [PATCH 3/3] spi: omap2-mcspi: Use the SPI framework to handle DMA mapping Franklin S Cooper Jr

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).