Commit 07e7716c authored by Robert Jarzmik's avatar Robert Jarzmik Committed by Ulf Hansson

mmc: pxamci: fix the device-tree probe deferral path

When the gpio driver is probed after the mmc one, the read/write gpio
and card detection one return -EPROBE_DEFER. Unfortunately, the memory
region remains requested, and upon the next probe, the probe will fail
anyway with -EBUSY.

Fix this by releasing the memory resource upon probe failure.

More broadly, this patch uses devm_*() primitives whenever possible in
the probe function.
Signed-off-by: default avatarRobert Jarzmik <robert.jarzmik@free.fr>
Signed-off-by: default avatarUlf Hansson <ulf.hansson@linaro.org>
parent b0066312
...@@ -86,7 +86,7 @@ struct pxamci_host { ...@@ -86,7 +86,7 @@ struct pxamci_host {
static inline void pxamci_init_ocr(struct pxamci_host *host) static inline void pxamci_init_ocr(struct pxamci_host *host)
{ {
#ifdef CONFIG_REGULATOR #ifdef CONFIG_REGULATOR
host->vcc = regulator_get_optional(mmc_dev(host->mmc), "vmmc"); host->vcc = devm_regulator_get_optional(mmc_dev(host->mmc), "vmmc");
if (IS_ERR(host->vcc)) if (IS_ERR(host->vcc))
host->vcc = NULL; host->vcc = NULL;
...@@ -654,12 +654,8 @@ static int pxamci_probe(struct platform_device *pdev) ...@@ -654,12 +654,8 @@ static int pxamci_probe(struct platform_device *pdev)
r = platform_get_resource(pdev, IORESOURCE_MEM, 0); r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
irq = platform_get_irq(pdev, 0); irq = platform_get_irq(pdev, 0);
if (!r || irq < 0) if (irq < 0)
return -ENXIO; return irq;
r = request_mem_region(r->start, SZ_4K, DRIVER_NAME);
if (!r)
return -EBUSY;
mmc = mmc_alloc_host(sizeof(struct pxamci_host), &pdev->dev); mmc = mmc_alloc_host(sizeof(struct pxamci_host), &pdev->dev);
if (!mmc) { if (!mmc) {
...@@ -695,7 +691,7 @@ static int pxamci_probe(struct platform_device *pdev) ...@@ -695,7 +691,7 @@ static int pxamci_probe(struct platform_device *pdev)
host->pdata = pdev->dev.platform_data; host->pdata = pdev->dev.platform_data;
host->clkrt = CLKRT_OFF; host->clkrt = CLKRT_OFF;
host->clk = clk_get(&pdev->dev, NULL); host->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(host->clk)) { if (IS_ERR(host->clk)) {
ret = PTR_ERR(host->clk); ret = PTR_ERR(host->clk);
host->clk = NULL; host->clk = NULL;
...@@ -727,9 +723,9 @@ static int pxamci_probe(struct platform_device *pdev) ...@@ -727,9 +723,9 @@ static int pxamci_probe(struct platform_device *pdev)
host->irq = irq; host->irq = irq;
host->imask = MMC_I_MASK_ALL; host->imask = MMC_I_MASK_ALL;
host->base = ioremap(r->start, SZ_4K); host->base = devm_ioremap_resource(&pdev->dev, r);
if (!host->base) { if (IS_ERR(host->base)) {
ret = -ENOMEM; ret = PTR_ERR(host->base);
goto out; goto out;
} }
...@@ -742,7 +738,8 @@ static int pxamci_probe(struct platform_device *pdev) ...@@ -742,7 +738,8 @@ static int pxamci_probe(struct platform_device *pdev)
writel(64, host->base + MMC_RESTO); writel(64, host->base + MMC_RESTO);
writel(host->imask, host->base + MMC_I_MASK); writel(host->imask, host->base + MMC_I_MASK);
ret = request_irq(host->irq, pxamci_irq, 0, DRIVER_NAME, host); ret = devm_request_irq(&pdev->dev, host->irq, pxamci_irq, 0,
DRIVER_NAME, host);
if (ret) if (ret)
goto out; goto out;
...@@ -833,14 +830,9 @@ static int pxamci_probe(struct platform_device *pdev) ...@@ -833,14 +830,9 @@ static int pxamci_probe(struct platform_device *pdev)
dma_release_channel(host->dma_chan_rx); dma_release_channel(host->dma_chan_rx);
if (host->dma_chan_tx) if (host->dma_chan_tx)
dma_release_channel(host->dma_chan_tx); dma_release_channel(host->dma_chan_tx);
if (host->base)
iounmap(host->base);
if (host->clk)
clk_put(host->clk);
} }
if (mmc) if (mmc)
mmc_free_host(mmc); mmc_free_host(mmc);
release_resource(r);
return ret; return ret;
} }
...@@ -859,9 +851,6 @@ static int pxamci_remove(struct platform_device *pdev) ...@@ -859,9 +851,6 @@ static int pxamci_remove(struct platform_device *pdev)
gpio_ro = host->pdata->gpio_card_ro; gpio_ro = host->pdata->gpio_card_ro;
gpio_power = host->pdata->gpio_power; gpio_power = host->pdata->gpio_power;
} }
if (host->vcc)
regulator_put(host->vcc);
if (host->pdata && host->pdata->exit) if (host->pdata && host->pdata->exit)
host->pdata->exit(&pdev->dev, mmc); host->pdata->exit(&pdev->dev, mmc);
...@@ -870,16 +859,10 @@ static int pxamci_remove(struct platform_device *pdev) ...@@ -870,16 +859,10 @@ static int pxamci_remove(struct platform_device *pdev)
END_CMD_RES|PRG_DONE|DATA_TRAN_DONE, END_CMD_RES|PRG_DONE|DATA_TRAN_DONE,
host->base + MMC_I_MASK); host->base + MMC_I_MASK);
free_irq(host->irq, host);
dmaengine_terminate_all(host->dma_chan_rx); dmaengine_terminate_all(host->dma_chan_rx);
dmaengine_terminate_all(host->dma_chan_tx); dmaengine_terminate_all(host->dma_chan_tx);
dma_release_channel(host->dma_chan_rx); dma_release_channel(host->dma_chan_rx);
dma_release_channel(host->dma_chan_tx); dma_release_channel(host->dma_chan_tx);
iounmap(host->base);
clk_put(host->clk);
release_resource(host->res);
mmc_free_host(mmc); mmc_free_host(mmc);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment