Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 62ac52b2 authored by David Lechner's avatar David Lechner Committed by Ulf Hansson
Browse files

mmc: davinci: fix unwinding in probe



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.

Signed-off-by: default avatarDavid Lechner <david@lechnology.com>
Signed-off-by: default avatarUlf Hansson <ulf.hansson@linaro.org>
parent 2edeb854
Loading
Loading
Loading
Loading
+40 −60
Original line number Diff line number Diff line
@@ -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,40 @@ 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);
	if (!host->base)
		goto out;
	host->base = devm_ioremap(&pdev->dev, mem->start, mem_size);
	if (!host->base) {
		ret = -ENOMEM;
		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 +1266,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,14 +1323,16 @@ 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,
		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,29 +1346,19 @@ 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) {
dma_probe_defer:
	clk_disable(host->clk);
			clk_put(host->clk);
		}

		if (host->base)
			iounmap(host->base);
	}

	if (mmc)
clk_enable_fail:
clk_get_fail:
ioremap_fail:
	mmc_free_host(mmc);

	if (mem)
		release_resource(mem);

	dev_dbg(&pdev->dev, "probe err %d\n", ret);

	return ret;
}

@@ -1372,25 +1366,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);

	mmc_davinci_cpufreq_deregister(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);
	}

	return 0;
}