Skip to contentSkip to conversation

davinci_mmc fixes

PATCH Applied David Lechner 2 participants 10 messages Mar 17, 2016 – Apr 5, 2016

Subsystems (4)

v3 of 4 Applied Latest is v4 →

lore
Share & tools
lore
#0 lore raw

v3 cover davinci_mmc fixes

I have replaced one of my patches with the patch from Peter Ujfalusi and fixed a mistake in the "fix unwinding..." patch.

Tested working on LEGO MINDSTORMS EV3 (da850-ish).

David Lechner (4):
mmc: davinci: remove matching string
mmc: davinci: fix unwinding in probe
mmc: davinci: prepare clock
ARM: davinci: remove mmc dma resources

Peter Ujfalusi (1):
mmc: davinci_mmc: Use dma_request_chan() to requesting DMA channel

 arch/arm/mach-davinci/devices-da8xx.c |  20 -----
 arch/arm/mach-davinci/devices.c       |  16 ----
 drivers/mmc/host/davinci_mmc.c        | 147 ++++++++++++----------------------
 3 files changed, 50 insertions(+), 133 deletions(-)
Signature · 1 line
1.9.1
#1 lore raw

PATCH v3 1/5 mmc: davinci_mmc: Use dma_request_chan() to requesting DMA channel

From: Peter Ujfalusi <[email protected]>

With the new dma_request_chan() the client driver does not need to look for the DMA resource and it does not need to pass filter_fn anymore. By switching to the new API the driver can now support deferred probing against DMA.

---

v3 changes: This is a new patch in v3 (from Peter Ujfalusi) and replaces my previous "mmc: davinci: don't use dma platform resources" patch.

 drivers/mmc/host/davinci_mmc.c | 53 +++++++++++-------------------------------
 1 file changed, 14 insertions(+), 39 deletions(-)
drivers/mmc/host/davinci_mmc.c +14 -39
index 693144e..eb3ca9e 100644
@@ -32,12 +32,10 @@
 #include <linux/delay.h>
 #include <linux/dmaengine.h>
 #include <linux/dma-mapping.h>
-#include <linux/edma.h>
 #include <linux/mmc/mmc.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
 
-#include <linux/platform_data/edma.h>
 #include <linux/platform_data/mmc-davinci.h>
 
 /*
@@ -202,7 +200,6 @@ struct mmc_davinci_host {
 	u32 buffer_bytes_left;
 	u32 bytes_left;
 
-	u32 rxdma, txdma;
 	struct dma_chan *dma_tx;
 	struct dma_chan *dma_rx;
 	bool use_dma;
@@ -513,35 +510,20 @@ davinci_release_dma_channels(struct mmc_davinci_host *host)
 
 static int __init davinci_acquire_dma_channels(struct mmc_davinci_host *host)
 {
-	int r;
-	dma_cap_mask_t mask;
-
-	dma_cap_zero(mask);
-	dma_cap_set(DMA_SLAVE, mask);
-
-	host->dma_tx =
-		dma_request_slave_channel_compat(mask, edma_filter_fn,
-				&host->txdma, mmc_dev(host->mmc), "tx");
-	if (!host->dma_tx) {
+	host->dma_tx = dma_request_chan(mmc_dev(host->mmc), "tx");
+	if (IS_ERR(host->dma_tx)) {
 		dev_err(mmc_dev(host->mmc), "Can't get dma_tx channel\n");
-		return -ENODEV;
+		return PTR_ERR(host->dma_tx);
 	}
 
-	host->dma_rx =
-		dma_request_slave_channel_compat(mask, edma_filter_fn,
-				&host->rxdma, mmc_dev(host->mmc), "rx");
-	if (!host->dma_rx) {
+	host->dma_rx = dma_request_chan(mmc_dev(host->mmc), "rx");
+	if (IS_ERR(host->dma_rx)) {
 		dev_err(mmc_dev(host->mmc), "Can't get dma_rx channel\n");
-		r = -ENODEV;
-		goto free_master_write;
+		dma_release_channel(host->dma_tx);
+		return PTR_ERR(host->dma_rx);
 	}
 
 	return 0;
-
-free_master_write:
-	dma_release_channel(host->dma_tx);
-
-	return r;
 }
 
 /*----------------------------------------------------------------------*/
@@ -1253,18 +1235,6 @@ static int __init davinci_mmcsd_probe(struct platform_device *pdev)
 	host = mmc_priv(mmc);
 	host->mmc = mmc;	/* Important */
 
-	r = platform_get_resource(pdev, IORESOURCE_DMA, 0);
-	if (!r)
-		dev_warn(&pdev->dev, "RX DMA resource not specified\n");
-	else
-		host->rxdma = r->start;
-
-	r = platform_get_resource(pdev, IORESOURCE_DMA, 1);
-	if (!r)
-		dev_warn(&pdev->dev, "TX DMA resource not specified\n");
-	else
-		host->txdma = r->start;
-
 	host->mem_res = mem;
 	host->base = ioremap(mem->start, mem_size);
 	if (!host->base)
@@ -1291,8 +1261,13 @@ static int __init davinci_mmcsd_probe(struct platform_device *pdev)
 	host->mmc_irq = irq;
 	host->sdio_irq = platform_get_irq(pdev, 1);
 
-	if (host->use_dma && davinci_acquire_dma_channels(host) != 0)
-		host->use_dma = 0;
+	if (host->use_dma) {
+		ret = davinci_acquire_dma_channels(host);
+		if (ret == -EPROBE_DEFER)
+			goto out;
+		else if (ret)
+			host->use_dma = 0;
+	}
 
 	/* REVISIT:  someday, support IRQ-driven card detection.  */
 	mmc->caps |= MMC_CAP_NEEDS_POLL;
Signature · 1 line
1.9.1
#2 lore raw

PATCH v3 2/5 mmc: davinci: remove matching string

In reply to David Lechner

The string "MMCSDCLK" is not actually used for clock lookup, so can be removed.

---

v3 changes: none.

 drivers/mmc/host/davinci_mmc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/mmc/host/davinci_mmc.c +1 -1
index eb3ca9e..498c42d 100644
@@ -1241,7 +1241,7 @@ static int __init davinci_mmcsd_probe(struct platform_device *pdev)
 		goto out;
 
 	ret = -ENXIO;
-	host->clk = clk_get(&pdev->dev, "MMCSDCLK");
+	host->clk = clk_get(&pdev->dev, NULL);
 	if (IS_ERR(host->clk)) {
 		ret = PTR_ERR(host->clk);
 		goto out;
Signature · 1 line
1.9.1
#3 lore raw

PATCH v3 3/5 mmc: davinci: fix unwinding in probe

In reply to David Lechner

Unwiding from an error in davinci_mmcsd_probe was a mess. Some errors were not handled and not all paths unwound correctly. Also using devm_ where possible to simplify things.

---

v3 changes: fixed ret = -ENODEV mistake. Updated to apply on top of patch from Peter Ujfalusi.

 drivers/mmc/host/davinci_mmc.c | 96 ++++++++++++++++--------------------------
 1 file changed, 37 insertions(+), 59 deletions(-)
drivers/mmc/host/davinci_mmc.c +37 -59
index 498c42d..e75407d 100644
@@ -1205,7 +1205,7 @@ static int __init davinci_mmcsd_probe(struct platform_device *pdev)
 	struct mmc_davinci_host *host = NULL;
 	struct mmc_host *mmc = NULL;
 	struct resource *r, *mem = NULL;
-	int ret = 0, irq = 0;
+	int ret, irq;
 	size_t mem_size;
 	const struct platform_device_id *id_entry;
 
@@ -1215,38 +1215,38 @@ static int __init davinci_mmcsd_probe(struct platform_device *pdev)
 		return -ENOENT;
 	}
 
-	ret = -ENODEV;
 	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	irq = platform_get_irq(pdev, 0);
 	if (!r || irq == NO_IRQ)
-		goto out;
+		return -ENODEV;
 
-	ret = -EBUSY;
 	mem_size = resource_size(r);
-	mem = request_mem_region(r->start, mem_size, pdev->name);
+	mem = devm_request_mem_region(&pdev->dev, r->start, mem_size,
+				      pdev->name);
 	if (!mem)
-		goto out;
+		return -EBUSY;
 
-	ret = -ENOMEM;
 	mmc = mmc_alloc_host(sizeof(struct mmc_davinci_host), &pdev->dev);
 	if (!mmc)
-		goto out;
+		return -ENOMEM;
 
 	host = mmc_priv(mmc);
 	host->mmc = mmc;	/* Important */
 
 	host->mem_res = mem;
-	host->base = ioremap(mem->start, mem_size);
+	host->base = devm_ioremap(&pdev->dev, mem->start, mem_size);
 	if (!host->base)
-		goto out;
+		goto ioremap_fail;
 
-	ret = -ENXIO;
-	host->clk = clk_get(&pdev->dev, NULL);
+	host->clk = devm_clk_get(&pdev->dev, NULL);
 	if (IS_ERR(host->clk)) {
 		ret = PTR_ERR(host->clk);
-		goto out;
+		goto clk_get_fail;
 	}
-	clk_enable(host->clk);
+	ret = clk_enable(host->clk);
+	if (ret)
+		goto clk_enable_fail;
+
 	host->mmc_input_clk = clk_get_rate(host->clk);
 
 	init_mmcsd_host(host);
@@ -1264,7 +1264,7 @@ static int __init davinci_mmcsd_probe(struct platform_device *pdev)
 	if (host->use_dma) {
 		ret = davinci_acquire_dma_channels(host);
 		if (ret == -EPROBE_DEFER)
-			goto out;
+			goto dma_probe_defer;
 		else if (ret)
 			host->use_dma = 0;
 	}
@@ -1321,15 +1321,17 @@ static int __init davinci_mmcsd_probe(struct platform_device *pdev)
 
 	ret = mmc_add_host(mmc);
 	if (ret < 0)
-		goto out;
+		goto mmc_add_host_fail;
 
-	ret = request_irq(irq, mmc_davinci_irq, 0, mmc_hostname(mmc), host);
+	ret = devm_request_irq(&pdev->dev, irq, mmc_davinci_irq, 0,
+			       mmc_hostname(mmc), host);
 	if (ret)
-		goto out;
+		goto request_irq_fail;
 
 	if (host->sdio_irq >= 0) {
-		ret = request_irq(host->sdio_irq, mmc_davinci_sdio_irq, 0,
-				  mmc_hostname(mmc), host);
+		ret = devm_request_irq(&pdev->dev, host->sdio_irq,
+				       mmc_davinci_sdio_irq, 0,
+				       mmc_hostname(mmc), host);
 		if (!ret)
 			mmc->caps |= MMC_CAP_SDIO_IRQ;
 	}
@@ -1342,28 +1344,18 @@ static int __init davinci_mmcsd_probe(struct platform_device *pdev)
 
 	return 0;
 
-out:
+request_irq_fail:
+	mmc_remove_host(mmc);
+mmc_add_host_fail:
 	mmc_davinci_cpufreq_deregister(host);
 cpu_freq_fail:
-	if (host) {
-		davinci_release_dma_channels(host);
-
-		if (host->clk) {
-			clk_disable(host->clk);
-			clk_put(host->clk);
-		}
-
-		if (host->base)
-			iounmap(host->base);
-	}
-
-	if (mmc)
-		mmc_free_host(mmc);
-
-	if (mem)
-		release_resource(mem);
-
-	dev_dbg(&pdev->dev, "probe err %d\n", ret);
+	davinci_release_dma_channels(host);
+dma_probe_defer:
+	clk_disable(host->clk);
+clk_enable_fail:
+clk_get_fail:
+ioremap_fail:
+	mmc_free_host(mmc);
 
 	return ret;
 }
@@ -1372,25 +1364,11 @@ static int __exit davinci_mmcsd_remove(struct platform_device *pdev)
 {
 	struct mmc_davinci_host *host = platform_get_drvdata(pdev);
 
-	if (host) {
-		mmc_davinci_cpufreq_deregister(host);
-
-		mmc_remove_host(host->mmc);
-		free_irq(host->mmc_irq, host);
-		if (host->mmc->caps & MMC_CAP_SDIO_IRQ)
-			free_irq(host->sdio_irq, host);
-
-		davinci_release_dma_channels(host);
-
-		clk_disable(host->clk);
-		clk_put(host->clk);
-
-		iounmap(host->base);
-
-		release_resource(host->mem_res);
-
-		mmc_free_host(host->mmc);
-	}
+	mmc_remove_host(host->mmc);
+	mmc_davinci_cpufreq_deregister(host);
+	davinci_release_dma_channels(host);
+	clk_disable(host->clk);
+	mmc_free_host(host->mmc);
 
 	return 0;
 }
Signature · 1 line
1.9.1
#4 lore raw

PATCH v3 4/5 mmc: davinci: prepare clock

In reply to David Lechner

When trying to use this driver with the common clock framework, enabling the clock fails because it was not prepared. This fixes the problem by calling clk_prepare and clk_enable in a single function. Ditto for clk_disable_unprepare.

---

v3 changes: none.

 drivers/mmc/host/davinci_mmc.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)
drivers/mmc/host/davinci_mmc.c +5 -5
index e75407d..d5d931b 100644
@@ -1243,9 +1243,9 @@ static int __init davinci_mmcsd_probe(struct platform_device *pdev)
 		ret = PTR_ERR(host->clk);
 		goto clk_get_fail;
 	}
-	ret = clk_enable(host->clk);
+	ret = clk_prepare_enable(host->clk);
 	if (ret)
-		goto clk_enable_fail;
+		goto clk_prepare_enable_fail;
 
 	host->mmc_input_clk = clk_get_rate(host->clk);
 
@@ -1351,8 +1351,8 @@ mmc_add_host_fail:
 cpu_freq_fail:
 	davinci_release_dma_channels(host);
 dma_probe_defer:
-	clk_disable(host->clk);
-clk_enable_fail:
+	clk_disable_unprepare(host->clk);
+clk_prepare_enable_fail:
 clk_get_fail:
 ioremap_fail:
 	mmc_free_host(mmc);
@@ -1367,7 +1367,7 @@ static int __exit davinci_mmcsd_remove(struct platform_device *pdev)
 	mmc_remove_host(host->mmc);
 	mmc_davinci_cpufreq_deregister(host);
 	davinci_release_dma_channels(host);
-	clk_disable(host->clk);
+	clk_disable_unprepare(host->clk);
 	mmc_free_host(host->mmc);
 
 	return 0;
Signature · 1 line
1.9.1
#5 lore raw

PATCH v3 5/5 ARM: davinci: remove mmc dma resources

In reply to David Lechner

The davinci_mmc driver no longer uses platform resources for getting dma channels. Instead lookup is now done using dma_slave_map.

---

v3 changes: none.

 arch/arm/mach-davinci/devices-da8xx.c | 20 --------------------
 arch/arm/mach-davinci/devices.c       | 16 ----------------
 2 files changed, 36 deletions(-)
arch/arm/mach-davinci/devices-da8xx.c +0 -20
index 725e693..add3771 100644
@@ -751,16 +751,6 @@ static struct resource da8xx_mmcsd0_resources[] = {
 		.end	= IRQ_DA8XX_MMCSDINT0,
 		.flags	= IORESOURCE_IRQ,
 	},
-	{		/* DMA RX */
-		.start	= DA8XX_DMA_MMCSD0_RX,
-		.end	= DA8XX_DMA_MMCSD0_RX,
-		.flags	= IORESOURCE_DMA,
-	},
-	{		/* DMA TX */
-		.start	= DA8XX_DMA_MMCSD0_TX,
-		.end	= DA8XX_DMA_MMCSD0_TX,
-		.flags	= IORESOURCE_DMA,
-	},
 };
 
 static struct platform_device da8xx_mmcsd0_device = {
@@ -788,16 +778,6 @@ static struct resource da850_mmcsd1_resources[] = {
 		.end	= IRQ_DA850_MMCSDINT0_1,
 		.flags	= IORESOURCE_IRQ,
 	},
-	{		/* DMA RX */
-		.start	= DA850_DMA_MMCSD1_RX,
-		.end	= DA850_DMA_MMCSD1_RX,
-		.flags	= IORESOURCE_DMA,
-	},
-	{		/* DMA TX */
-		.start	= DA850_DMA_MMCSD1_TX,
-		.end	= DA850_DMA_MMCSD1_TX,
-		.flags	= IORESOURCE_DMA,
-	},
 };
 
 static struct platform_device da850_mmcsd1_device = {
arch/arm/mach-davinci/devices.c +0 -16
index 6257aa4..67d26c5 100644
@@ -144,14 +144,6 @@ static struct resource mmcsd0_resources[] = {
 		.start = IRQ_SDIOINT,
 		.flags = IORESOURCE_IRQ,
 	},
-	/* DMA channels: RX, then TX */
-	{
-		.start = EDMA_CTLR_CHAN(0, DAVINCI_DMA_MMCRXEVT),
-		.flags = IORESOURCE_DMA,
-	}, {
-		.start = EDMA_CTLR_CHAN(0, DAVINCI_DMA_MMCTXEVT),
-		.flags = IORESOURCE_DMA,
-	},
 };
 
 static struct platform_device davinci_mmcsd0_device = {
@@ -181,14 +173,6 @@ static struct resource mmcsd1_resources[] = {
 		.start = IRQ_DM355_SDIOINT1,
 		.flags = IORESOURCE_IRQ,
 	},
-	/* DMA channels: RX, then TX */
-	{
-		.start = EDMA_CTLR_CHAN(0, 30),	/* rx */
-		.flags = IORESOURCE_DMA,
-	}, {
-		.start = EDMA_CTLR_CHAN(0, 31),	/* tx */
-		.flags = IORESOURCE_DMA,
-	},
 };
 
 static struct platform_device davinci_mmcsd1_device = {
Signature · 1 line
1.9.1
Applied
#6 lore raw
In reply to David Lechner
Quoted 14 lines · David Lechner

I have replaced one of my patches with the patch from Peter Ujfalusi and fixed a mistake in the "fix unwinding..." patch.

Tested working on LEGO MINDSTORMS EV3 (da850-ish).

David Lechner (4):
mmc: davinci: remove matching string
mmc: davinci: fix unwinding in probe
mmc: davinci: prepare clock
ARM: davinci: remove mmc dma resources

Peter Ujfalusi (1):
mmc: davinci_mmc: Use dma_request_chan() to requesting DMA channel

Quoted 8 lines
 arch/arm/mach-davinci/devices-da8xx.c |  20 -----
 arch/arm/mach-davinci/devices.c       |  16 ----
 drivers/mmc/host/davinci_mmc.c        | 147 ++++++++++++----------------------
 3 files changed, 50 insertions(+), 133 deletions(-)

--
1.9.1

Patch 3 triggers a compiler warning, please fix it.

../drivers/mmc/host/davinci_mmc.c: In function ?davinci_mmcsd_probe?:
../drivers/mmc/host/davinci_mmc.c:1208:6: warning: ?ret? may be used uninitialized in this function [-Wmaybe-uninitialized]

I have applied patch 1->2 for next, so no need to resend these.

Kind regards
Uffe

#7 lore raw
Quoted 12 lines · Ulf Hansson

Patch 3 triggers a compiler warning, please fix it.

../drivers/mmc/host/davinci_mmc.c: In function ‘davinci_mmcsd_probe’:
../drivers/mmc/host/davinci_mmc.c:1208:6: warning: ‘ret’ may be used uninitialized in this function [-Wmaybe-uninitialized]

I have applied patch 1->2 for next, so no need to resend these.

Kind regards
Uffe

I am not getting a compiler warning with this commit. Can you please provide a git link so that I can be sure I am building using the same branch that you are using?

#8 lore raw
Quoted 10 lines · David Lechner
Quoted 9 lines · Ulf Hansson

Patch 3 triggers a compiler warning, please fix it.

../drivers/mmc/host/davinci_mmc.c: In function ‘davinci_mmcsd_probe’:
../drivers/mmc/host/davinci_mmc.c:1208:6: warning: ‘ret’ may be used uninitialized in this function [-Wmaybe-uninitialized]

I have applied patch 1->2 for next, so no need to resend these.

Quoted 7 lines
Quoted 3 lines

Kind regards
Uffe

I am not getting a compiler warning with this commit. Can you please provide a git link so that I can be sure I am building using the same branch that you are using?

I think I figured it out. I am applying the patches on top of the next branch from git://git.linaro.org/people/ulf.hansson/mmc.git. However, I am still not getting a compiler warning. Perhaps it has to do with the gcc version. I'm not exactly sure how to fix it since it is really not used uninitialized. Just set it to 0 in the variable declaration?

#9 lore raw
Quoted 20 lines · David Lechner
Quoted 10 lines · David Lechner
Quoted 9 lines · Ulf Hansson

Patch 3 triggers a compiler warning, please fix it.

../drivers/mmc/host/davinci_mmc.c: In function ‘davinci_mmcsd_probe’:
../drivers/mmc/host/davinci_mmc.c:1208:6: warning: ‘ret’ may be used uninitialized in this function [-Wmaybe-uninitialized]

I have applied patch 1->2 for next, so no need to resend these.

Quoted 7 lines
Quoted 3 lines

Kind regards
Uffe

I am not getting a compiler warning with this commit. Can you please provide a git link so that I can be sure I am building using the same branch that you are using?

Quoted 5 lines

I think I figured it out. I am applying the patches on top of the next branch from git://git.linaro.org/people/ulf.hansson/mmc.git. However, I am still not getting a compiler warning. Perhaps it has to do with the gcc version. I'm not exactly sure how to fix it since it is really not used uninitialized. Just set it to 0 in the variable declaration?

OK. I guess it is my compiler that is broken. :-/ I stared at it long enough and I see the error now.