public inbox for linux-arm-kernel@lists.infradead.org
 help / color / mirror / Atom feed
From: arnd@arndb.de (Arnd Bergmann)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 13/15] ASoC: SND_S3C_DMA_LEGACY needs S3C24XX_DMA
Date: Fri, 02 May 2014 18:10:41 +0200	[thread overview]
Message-ID: <23328024.fZtE3FFkWh@wuerfel> (raw)
In-Reply-To: <11471248.qyIXLf6t3H@diego>

On Friday 02 May 2014 12:25:58 Heiko St?bner wrote:
> 
> Just to mention, we have a dmaengine driver for s3c24xx  . Correct 
> platform-data is present for all s3c24xx socs (in mach-s3c24xx/common.c) .
> 
> Mark already removed support for the legacy API from the s3c64xx spi driver 
> (used by s3c2416 and s3c2443), so I guess to way forward would be to "simply" 
> convert asoc and s3cmci to dmaengine and get rid of it altogether.

For asoc, this is probably very simple: the dma.c gets replaced with the
dmaengine.c, and the three drivers calling s3c2410_dma_ctrl(dma_data->channel, S3C2410_DMAOP_STARTED) get changed to do something equivalent.

> I just never had hardware using the old mci driver or with any previously 
> working sound and didn't trust my experience to be enough to be able to do 
> such a conversion "on the fly" like you below in the opposite direction 

What I did was much easier: the dma.c file was already using a wrapper
around both interfaces, I just unwrapped it. For mci, you'd have to
replace one API with another incompatible one. I've tried a conversion
in the patch below, but I also don't enough confidence in this to
submit it.

What is interesting however is that none of the three defconfigs we have
for S3C24xx actually uses DMA wiht MMC_S3C: tct_hammer doesn't have
any MMC support, and mini2440_defonfig as well as s3c2410_defconfig
enable the MMC driver in PIO-only mode.

When Ben Dooks did all the changes to the DMA code in that driver, but
he also marked DMA support as 'EXPERIMENTAL'. Maybe we can just get
away with deprecating that?

	Arnd

8<------
Subject: convert s3cmci to use dmaengine

This is an attempt to migrate s3cmci from the samsung-proprietary DMA
interface to the generic dmaengine API. I don't really understand
what I'm doing here, and this is not tested at all. Somebody who
has the hardware and understands this code can probably get it to
work, but I would expect a couple of small bugs to get introduced.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>

diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c
index f237826..02847d3 100644
--- a/drivers/mmc/host/s3cmci.c
+++ b/drivers/mmc/host/s3cmci.c
@@ -14,6 +14,7 @@
 #include <linux/module.h>
 #include <linux/dma-mapping.h>
 #include <linux/clk.h>
+#include <linux/dmaengine.h>
 #include <linux/mmc/host.h>
 #include <linux/platform_device.h>
 #include <linux/cpufreq.h>
@@ -28,6 +29,7 @@
 #include <mach/gpio-samsung.h>
 
 #include <linux/platform_data/mmc-s3cmci.h>
+#include <linux/platform_data/dma-s3c24xx.h>
 
 #include "s3cmci.h"
 
@@ -140,10 +142,6 @@ static const int dbgmap_debug = dbg_err | dbg_debug;
 		dev_dbg(&host->pdev->dev, args);  \
 	} while (0)
 
-static struct s3c2410_dma_client s3cmci_dma_client = {
-	.name		= "s3c-mci",
-};
-
 static void finalize_request(struct s3cmci_host *host);
 static void s3cmci_send_request(struct mmc_host *mmc);
 static void s3cmci_reset(struct s3cmci_host *host);
@@ -841,9 +839,7 @@ static irqreturn_t s3cmci_irq_cd(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
-static void s3cmci_dma_done_callback(struct s3c2410_dma_chan *dma_ch,
-				     void *buf_id, int size,
-				     enum s3c2410_dma_buffresult result)
+static void s3cmci_dma_done_callback(void *buf_id)
 {
 	struct s3cmci_host *host = buf_id;
 	unsigned long iflags;
@@ -856,45 +852,18 @@ static void s3cmci_dma_done_callback(struct s3c2410_dma_chan *dma_ch,
 
 	BUG_ON(!host->mrq);
 	BUG_ON(!host->mrq->data);
-	BUG_ON(!host->dmatogo);
 
 	spin_lock_irqsave(&host->complete_lock, iflags);
 
-	if (result != S3C2410_RES_OK) {
-		dbg(host, dbg_fail, "DMA FAILED: csta=0x%08x dsta=0x%08x "
-			"fsta=0x%08x dcnt:0x%08x result:0x%08x toGo:%u\n",
-			mci_csta, mci_dsta, mci_fsta,
-			mci_dcnt, result, host->dmatogo);
-
-		goto fail_request;
-	}
-
-	host->dmatogo--;
-	if (host->dmatogo) {
-		dbg(host, dbg_dma, "DMA DONE  Size:%i DSTA:[%08x] "
-			"DCNT:[%08x] toGo:%u\n",
-			size, mci_dsta, mci_dcnt, host->dmatogo);
-
-		goto out;
-	}
-
-	dbg(host, dbg_dma, "DMA FINISHED Size:%i DSTA:%08x DCNT:%08x\n",
-		size, mci_dsta, mci_dcnt);
+	dbg(host, dbg_dma, "DMA FINISHED DSTA:%08x DCNT:%08x\n",
+		mci_dsta, mci_dcnt);
 
 	host->dma_complete = 1;
 	host->complete_what = COMPLETION_FINALIZE;
 
-out:
 	tasklet_schedule(&host->pio_tasklet);
 	spin_unlock_irqrestore(&host->complete_lock, iflags);
 	return;
-
-fail_request:
-	host->mrq->data->error = -EINVAL;
-	host->complete_what = COMPLETION_FINALIZE;
-	clear_imask(host);
-
-	goto out;
 }
 
 static void finalize_request(struct s3cmci_host *host)
@@ -966,7 +935,7 @@ static void finalize_request(struct s3cmci_host *host)
 	 * DMA channel and the fifo to clear out any garbage. */
 	if (mrq->data->error != 0) {
 		if (s3cmci_host_usedma(host))
-			s3c2410_dma_ctrl(host->dma, S3C2410_DMAOP_FLUSH);
+			dmaengine_terminate_all(host->dma);
 
 		if (host->is2440) {
 			/* Clear failure register and reset fifo. */
@@ -993,26 +962,27 @@ request_done:
 }
 
 static void s3cmci_dma_setup(struct s3cmci_host *host,
-			     enum dma_data_direction source)
+			     enum dma_transfer_direction source)
 {
-	static enum dma_data_direction last_source = -1;
-	static int setup_ok;
+	static enum dma_transfer_direction last_source = -1;
+	struct dma_slave_config slave_config;
 
 	if (last_source == source)
 		return;
 
-	last_source = source;
-
-	s3c2410_dma_devconfig(host->dma, source,
-			      host->mem->start + host->sdidata);
-
-	if (!setup_ok) {
-		s3c2410_dma_config(host->dma, 4);
-		s3c2410_dma_set_buffdone_fn(host->dma,
-					    s3cmci_dma_done_callback);
-		s3c2410_dma_setflags(host->dma, S3C2410_DMAF_AUTOSTART);
-		setup_ok = 1;
+	memset(&slave_config, 0, sizeof(struct dma_slave_config));
+	slave_config.direction = source;
+	if (source == DMA_DEV_TO_MEM) {
+		slave_config.src_addr = host->mem->start + host->sdidata;
+		slave_config.src_addr_width = 4;
+		slave_config.src_maxburst = 1;
+	} else {
+		slave_config.dst_addr = host->mem->start + host->sdidata;
+		slave_config.dst_addr_width = 4;
+		slave_config.dst_maxburst = 1;
 	}
+	last_source = source;
+	dmaengine_slave_config(host->dma, &slave_config);
 }
 
 static void s3cmci_send_command(struct s3cmci_host *host,
@@ -1162,41 +1132,33 @@ static int s3cmci_prepare_pio(struct s3cmci_host *host, struct mmc_data *data)
 
 static int s3cmci_prepare_dma(struct s3cmci_host *host, struct mmc_data *data)
 {
-	int dma_len, i;
-	int rw = data->flags & MMC_DATA_WRITE;
+	int dma_len;
+	int dir = data->flags & MMC_DATA_WRITE ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
+	struct dma_async_tx_descriptor *desc;
 
 	BUG_ON((data->flags & BOTH_DIR) == BOTH_DIR);
 
-	s3cmci_dma_setup(host, rw ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
-	s3c2410_dma_ctrl(host->dma, S3C2410_DMAOP_FLUSH);
-
-	dma_len = dma_map_sg(mmc_dev(host->mmc), data->sg, data->sg_len,
-			     rw ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
+	s3cmci_dma_setup(host, dir);
 
+	dma_len = dma_map_sg(mmc_dev(host->mmc), data->sg, data->sg_len, dir);
 	if (dma_len == 0)
 		return -ENOMEM;
 
-	host->dma_complete = 0;
-	host->dmatogo = dma_len;
-
-	for (i = 0; i < dma_len; i++) {
-		int res;
+	desc = dmaengine_prep_slave_sg(host->dma, data->sg, dma_len,
+				       dir, DMA_CTRL_ACK);
 
-		dbg(host, dbg_dma, "enqueue %i: %08x@%u\n", i,
-		    sg_dma_address(&data->sg[i]),
-		    sg_dma_len(&data->sg[i]));
+	if (!desc) {
+		dma_unmap_sg(mmc_dev(host->mmc), data->sg, dma_len, dir);
+		return -EIO;
+	}
 
-		res = s3c2410_dma_enqueue(host->dma, host,
-					  sg_dma_address(&data->sg[i]),
-					  sg_dma_len(&data->sg[i]));
+	host->dma_complete = 0;
 
-		if (res) {
-			s3c2410_dma_ctrl(host->dma, S3C2410_DMAOP_FLUSH);
-			return -EBUSY;
-		}
-	}
+	desc->callback = s3cmci_dma_done_callback;
+	desc->callback_param = host;
 
-	s3c2410_dma_ctrl(host->dma, S3C2410_DMAOP_START);
+	dmaengine_submit(desc);
+	dma_async_issue_pending(host->dma);
 
 	return 0;
 }
@@ -1765,9 +1727,14 @@ static int s3cmci_probe(struct platform_device *pdev)
 	/* depending on the dma state, get a dma channel to use. */
 
 	if (s3cmci_host_usedma(host)) {
-		host->dma = s3c2410_dma_request(DMACH_SDI, &s3cmci_dma_client,
-						host);
-		if (host->dma < 0) {
+		dma_cap_mask_t mask;
+        
+		dma_cap_zero(mask);
+		dma_cap_set(DMA_SLAVE, mask);
+
+		host->dma = dma_request_channel(mask, s3c24xx_dma_filter, (void *)DMACH_SDI);
+
+		if (!host->dma) {
 			dev_err(&pdev->dev, "cannot get DMA channel.\n");
 			if (!s3cmci_host_canpio()) {
 				ret = -EBUSY;
@@ -1816,9 +1783,9 @@ static int s3cmci_probe(struct platform_device *pdev)
 	mmc->max_segs		= 128;
 
 	dbg(host, dbg_debug,
-	    "probe: mode:%s mapped mci_base:%p irq:%u irq_cd:%u dma:%u.\n",
+	    "probe: mode:%s mapped mci_base:%p irq:%u irq_cd:%u.\n",
 	    (host->is2440?"2440":""),
-	    host->base, host->irq, host->irq_cd, host->dma);
+	    host->base, host->irq, host->irq_cd);
 
 	ret = s3cmci_cpufreq_register(host);
 	if (ret) {
@@ -1852,7 +1819,7 @@ static int s3cmci_probe(struct platform_device *pdev)
 
  probe_free_dma:
 	if (s3cmci_host_usedma(host))
-		s3c2410_dma_free(host->dma, &s3cmci_dma_client);
+		dma_release_channel(host->dma);
 
  probe_free_gpio_wp:
 	if (!host->pdata->no_wprotect)
@@ -1914,7 +1881,7 @@ static int s3cmci_remove(struct platform_device *pdev)
 	tasklet_disable(&host->pio_tasklet);
 
 	if (s3cmci_host_usedma(host))
-		s3c2410_dma_free(host->dma, &s3cmci_dma_client);
+		dma_release_channel(host->dma);
 
 	free_irq(host->irq, host);
 

  reply	other threads:[~2014-05-02 16:10 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <1398770316-19715-1-git-send-email-kaixu.xia@linaro.org>
2014-04-29 11:18 ` [PATCH 01/15] ASoC: CS42L51 and WM8962 codecs depend on INPUT Xia Kaixu
2014-04-30  2:31   ` [alsa-devel] " Brian Austin
2014-05-01  1:31     ` Mark Brown
2014-05-01  1:54       ` Austin, Brian
2014-05-01  2:16         ` Austin, Brian
2014-05-01  3:27           ` Mark Brown
2014-05-01 12:26             ` Austin, Brian
2014-05-01  1:30   ` Mark Brown
2014-04-29 11:18 ` [PATCH 03/15] ASoC: SMDK_WM8580_PCM needs REGMAP_I2C Xia Kaixu
2014-05-01  3:30   ` Mark Brown
2014-04-29 11:18 ` [PATCH 04/15] ASoC: samsung-idma: avoid 64-bit division Xia Kaixu
2014-04-30  3:50   ` Tushar Behera
2014-05-01  3:31   ` Mark Brown
2014-04-29 11:18 ` [PATCH 05/15] ASoC: nuc900: export nuc900_ac97_data Xia Kaixu
2014-05-01  3:32   ` Mark Brown
2014-04-29 11:18 ` [PATCH 07/15] ASoC: UDA1380 needs I2C Xia Kaixu
2014-05-01 17:59   ` Mark Brown
2014-04-29 11:18 ` [PATCH 08/15] ASoC: TTC DKB audio " Xia Kaixu
2014-05-01 18:01   ` Mark Brown
2014-04-29 11:18 ` [PATCH 09/15] ASoC: Migo-R sound " Xia Kaixu
2014-05-01 20:30   ` Mark Brown
2014-04-29 11:18 ` [PATCH 10/15] ASoC: TLV320AIC23 and Simtec Hermes audio Xia Kaixu
2014-05-01 20:29   ` Mark Brown
2014-04-29 11:18 ` [PATCH 11/15] ASoC: WM0010 needs SPI Xia Kaixu
2014-05-01 19:08   ` Mark Brown
2014-04-29 11:18 ` [PATCH 13/15] ASoC: SND_S3C_DMA_LEGACY needs S3C24XX_DMA Xia Kaixu
2014-05-01 19:11   ` Mark Brown
2014-05-01 22:35     ` Arnd Bergmann
2014-05-02 10:25       ` Heiko Stübner
2014-05-02 16:10         ` Arnd Bergmann [this message]
2014-05-02 17:26         ` Mark Brown
2014-05-02 17:24       ` Mark Brown
2014-04-29 11:18 ` [PATCH 15/15] ASoC: pxa: remove mach header dependency Xia Kaixu

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=23328024.fZtE3FFkWh@wuerfel \
    --to=arnd@arndb.de \
    --cc=linux-arm-kernel@lists.infradead.org \
    /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