linux-spi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Matt Porter <mporter@ti.com>
To: Tony Lindgren <tony@atomide.com>, Sekhar Nori <nsekhar@ti.com>,
	Grant Likely <grant.likely@secretlab.ca>,
	Mark Brown <broonie@opensource.wolfsonmicro.com>,
	Benoit Cousson <b-cousson@ti.com>,
	Russell King <linux@arm.linux.org.uk>,
	Vinod Koul <vinod.koul@intel.com>, Rob Landley <rob@landley.net>,
	Chris Ball <cjb@laptop.org>
Cc: Devicetree Discuss <devicetree-discuss@lists.ozlabs.org>,
	Linux OMAP List <linux-omap@vger.kernel.org>,
	Linux ARM Kernel List <linux-arm-kernel@lists.infradead.org>,
	Linux DaVinci Kernel List
	<davinci-linux-open-source@linux.davincidsp.com>,
	Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
	Linux Documentation List <linux-doc@vger.kernel.org>,
	Linux MMC List <linux-mmc@vger.kernel.org>,
	Linux SPI Devel List <spi-devel-general@lists.sourceforge.net>,
	Arnd Bergmann <arnd@arndb.de>, Dan Williams <djbw@fb.com>,
	Rob Herring <rob.herring@calxeda.com>
Subject: [RFC PATCH v2 01/16] dmaengine: edma: fix slave config dependency on direction
Date: Thu, 11 Oct 2012 15:04:26 -0400	[thread overview]
Message-ID: <1349982281-10785-2-git-send-email-mporter@ti.com> (raw)
In-Reply-To: <1349982281-10785-1-git-send-email-mporter@ti.com>

The edma_slave_config() implementation depends on the
direction field such that it will not properly configure
a slave channel when called without direction set.

This fixes the implementation so that the slave config
is copied as is and prep_slave_sg() handles the
direction dependent handling. spi-omap2-mcspi and
omap_hsmmc both expose this bug as they configure the
slave channel config from a common path with an unconfigured
direction field.

Signed-off-by: Matt Porter <mporter@ti.com>
---
 drivers/dma/edma.c |   55 ++++++++++++++++++++++++++--------------------------
 1 file changed, 27 insertions(+), 28 deletions(-)

diff --git a/drivers/dma/edma.c b/drivers/dma/edma.c
index 05aea3c..fdcf079 100644
--- a/drivers/dma/edma.c
+++ b/drivers/dma/edma.c
@@ -69,9 +69,7 @@ struct edma_chan {
 	int				ch_num;
 	bool				alloced;
 	int				slot[EDMA_MAX_SLOTS];
-	dma_addr_t			addr;
-	int				addr_width;
-	int				maxburst;
+	struct dma_slave_config		cfg;
 };
 
 struct edma_cc {
@@ -178,29 +176,14 @@ static int edma_terminate_all(struct edma_chan *echan)
 	return 0;
 }
 
-
 static int edma_slave_config(struct edma_chan *echan,
-	struct dma_slave_config *config)
+	struct dma_slave_config *cfg)
 {
-	if ((config->src_addr_width > DMA_SLAVE_BUSWIDTH_4_BYTES) ||
-	    (config->dst_addr_width > DMA_SLAVE_BUSWIDTH_4_BYTES))
+	if (cfg->src_addr_width == DMA_SLAVE_BUSWIDTH_8_BYTES ||
+	    cfg->dst_addr_width == DMA_SLAVE_BUSWIDTH_8_BYTES)
 		return -EINVAL;
 
-	if (config->direction == DMA_MEM_TO_DEV) {
-		if (config->dst_addr)
-			echan->addr = config->dst_addr;
-		if (config->dst_addr_width)
-			echan->addr_width = config->dst_addr_width;
-		if (config->dst_maxburst)
-			echan->maxburst = config->dst_maxburst;
-	} else if (config->direction == DMA_DEV_TO_MEM) {
-		if (config->src_addr)
-			echan->addr = config->src_addr;
-		if (config->src_addr_width)
-			echan->addr_width = config->src_addr_width;
-		if (config->src_maxburst)
-			echan->maxburst = config->src_maxburst;
-	}
+	memcpy(&echan->cfg, cfg, sizeof(echan->cfg));
 
 	return 0;
 }
@@ -235,6 +218,9 @@ static struct dma_async_tx_descriptor *edma_prep_slave_sg(
 	struct edma_chan *echan = to_edma_chan(chan);
 	struct device *dev = chan->device->dev;
 	struct edma_desc *edesc;
+	dma_addr_t dev_addr;
+	enum dma_slave_buswidth dev_width;
+	u32 burst;
 	struct scatterlist *sg;
 	int i;
 	int acnt, bcnt, ccnt, src, dst, cidx;
@@ -243,7 +229,20 @@ static struct dma_async_tx_descriptor *edma_prep_slave_sg(
 	if (unlikely(!echan || !sgl || !sg_len))
 		return NULL;
 
-	if (echan->addr_width == DMA_SLAVE_BUSWIDTH_UNDEFINED) {
+	if (direction == DMA_DEV_TO_MEM) {
+		dev_addr = echan->cfg.src_addr;
+		dev_width = echan->cfg.src_addr_width;
+		burst = echan->cfg.src_maxburst;
+	} else if (direction == DMA_MEM_TO_DEV) {
+		dev_addr = echan->cfg.dst_addr;
+		dev_width = echan->cfg.dst_addr_width;
+		burst = echan->cfg.dst_maxburst;
+	} else {
+		dev_err(dev, "%s: bad direction?\n", __func__);
+		return NULL;
+	}
+
+	if (dev_width == DMA_SLAVE_BUSWIDTH_UNDEFINED) {
 		dev_err(dev, "Undefined slave buswidth\n");
 		return NULL;
 	}
@@ -275,14 +274,14 @@ static struct dma_async_tx_descriptor *edma_prep_slave_sg(
 			}
 		}
 
-		acnt = echan->addr_width;
+		acnt = dev_width;
 
 		/*
 		 * If the maxburst is equal to the fifo width, use
 		 * A-synced transfers. This allows for large contiguous
 		 * buffer transfers using only one PaRAM set.
 		 */
-		if (echan->maxburst == 1) {
+		if (burst == 1) {
 			edesc->absync = false;
 			ccnt = sg_dma_len(sg) / acnt / (SZ_64K - 1);
 			bcnt = sg_dma_len(sg) / acnt - ccnt * (SZ_64K - 1);
@@ -302,7 +301,7 @@ static struct dma_async_tx_descriptor *edma_prep_slave_sg(
 		 */
 		} else {
 			edesc->absync = true;
-			bcnt = echan->maxburst;
+			bcnt = burst;
 			ccnt = sg_dma_len(sg) / (acnt * bcnt);
 			if (ccnt > (SZ_64K - 1)) {
 				dev_err(dev, "Exceeded max SG segment size\n");
@@ -313,13 +312,13 @@ static struct dma_async_tx_descriptor *edma_prep_slave_sg(
 
 		if (direction == DMA_MEM_TO_DEV) {
 			src = sg_dma_address(sg);
-			dst = echan->addr;
+			dst = dev_addr;
 			src_bidx = acnt;
 			src_cidx = cidx;
 			dst_bidx = 0;
 			dst_cidx = 0;
 		} else {
-			src = echan->addr;
+			src = dev_addr;
 			dst = sg_dma_address(sg);
 			src_bidx = 0;
 			src_cidx = 0;
-- 
1.7.9.5

  reply	other threads:[~2012-10-11 19:04 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-10-11 19:04 [RFC PATCH v2 00/16] DMA Engine support for AM33xx Matt Porter
2012-10-11 19:04 ` Matt Porter [this message]
2012-10-11 19:04 ` [RFC PATCH v2 04/16] ARM: edma: add DT and runtime PM support for AM335x Matt Porter
     [not found] ` <1349982281-10785-1-git-send-email-mporter-l0cyMroinI0@public.gmane.org>
2012-10-11 19:04   ` [RFC PATCH v2 02/16] ARM: davinci: move private EDMA API to arm/common Matt Porter
2012-10-11 19:04   ` [RFC PATCH v2 03/16] ARM: edma: remove unused transfer controller handlers Matt Porter
2012-10-11 19:04   ` [RFC PATCH v2 05/16] dmaengine: edma: enable build for AM33XX Matt Porter
2012-10-11 19:04   ` [RFC PATCH v2 06/16] dmaengine: edma: Add TI EDMA device tree binding Matt Porter
2012-10-11 19:04   ` [RFC PATCH v2 07/16] ARM: dts: add AM33XX EDMA support Matt Porter
2012-10-11 19:04   ` [RFC PATCH v2 08/16] ARM: omap: add hsmmc am33xx specific init Matt Porter
     [not found]     ` <1349982281-10785-9-git-send-email-mporter-l0cyMroinI0@public.gmane.org>
2012-10-12  9:17       ` Hebbar, Gururaja
2012-10-12 11:54         ` Matt Porter
2012-10-11 19:04   ` [RFC PATCH v2 09/16] dmaengine: add dma_request_slave_channel_compat() Matt Porter
2012-10-11 19:04   ` [RFC PATCH v2 10/16] mmc: omap_hsmmc: convert to dma_request_slave_channel_compat() Matt Porter
2012-10-11 19:04   ` [RFC PATCH v2 11/16] mmc: omap_hsmmc: limit max_segs with the EDMA DMAC Matt Porter
2012-10-11 19:04   ` [RFC PATCH v2 12/16] mmc: omap_hsmmc: add generic DMA request support to the DT binding Matt Porter
2012-10-11 19:04   ` [RFC PATCH v2 13/16] ARM: dts: add AM33XX MMC support Matt Porter
2012-10-11 19:04   ` [RFC PATCH v2 14/16] spi: omap2-mcspi: convert to dma_request_slave_channel_compat() Matt Porter
2012-10-11 19:04   ` [RFC PATCH v2 15/16] spi: omap2-mcspi: add generic DMA request support to the DT binding Matt Porter
2012-10-11 19:04   ` [RFC PATCH v2 16/16] ARM: dts: add AM33XX SPI support Matt Porter
2012-10-11 21:31   ` [RFC PATCH v2 00/16] DMA Engine support for AM33xx Grant Likely
2012-10-11 21:49     ` Matt Porter

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1349982281-10785-2-git-send-email-mporter@ti.com \
    --to=mporter@ti.com \
    --cc=arnd@arndb.de \
    --cc=b-cousson@ti.com \
    --cc=broonie@opensource.wolfsonmicro.com \
    --cc=cjb@laptop.org \
    --cc=davinci-linux-open-source@linux.davincidsp.com \
    --cc=devicetree-discuss@lists.ozlabs.org \
    --cc=djbw@fb.com \
    --cc=grant.likely@secretlab.ca \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mmc@vger.kernel.org \
    --cc=linux-omap@vger.kernel.org \
    --cc=linux@arm.linux.org.uk \
    --cc=nsekhar@ti.com \
    --cc=rob.herring@calxeda.com \
    --cc=rob@landley.net \
    --cc=spi-devel-general@lists.sourceforge.net \
    --cc=tony@atomide.com \
    --cc=vinod.koul@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).