Skip to content

Commit

Permalink
Platform device error handling cleanup
Browse files Browse the repository at this point in the history
This patch is part of Juha Yrjola's earlier patch to add platform device
error handling and a BUG_ON to verify if host == NULL

Signed-off-by: Carlos Eduardo Aguiar <carlos.aguiar <at> indt.org.br>
Signed-off-by: Juha Yrjola <juha.yrjola <at> solidboot.com>
Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
  • Loading branch information
Juha Yrjola juha.yrjola authored and Pierre Ossman committed Dec 1, 2006
1 parent 0551f4d commit 81ca703
Showing 1 changed file with 59 additions and 41 deletions.
100 changes: 59 additions & 41 deletions drivers/mmc/omap.c
Original file line number Diff line number Diff line change
Expand Up @@ -1022,25 +1022,29 @@ static int __init mmc_omap_probe(struct platform_device *pdev)
struct omap_mmc_conf *minfo = pdev->dev.platform_data;
struct mmc_host *mmc;
struct mmc_omap_host *host = NULL;
struct resource *r;
struct resource *res;
int ret = 0;
int irq;

r = platform_get_resource(pdev, IORESOURCE_MEM, 0);

if (minfo == NULL) {
dev_err(&pdev->dev, "platform data missing\n");
return -ENXIO;
}

res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
irq = platform_get_irq(pdev, 0);
if (!r || irq < 0)
if (res == NULL || irq < 0)
return -ENXIO;

r = request_mem_region(pdev->resource[0].start,
pdev->resource[0].end - pdev->resource[0].start + 1,
pdev->name);
if (!r)
res = request_mem_region(res->start, res->end - res->start + 1,
pdev->name);
if (res == NULL)
return -EBUSY;

mmc = mmc_alloc_host(sizeof(struct mmc_omap_host), &pdev->dev);
if (!mmc) {
if (mmc == NULL) {
ret = -ENOMEM;
goto out;
goto err_free_mem_region;
}

host = mmc_priv(mmc);
Expand All @@ -1052,13 +1056,13 @@ static int __init mmc_omap_probe(struct platform_device *pdev)
host->dma_timer.data = (unsigned long) host;

host->id = pdev->id;
host->mem_res = r;
host->mem_res = res;
host->irq = irq;

if (cpu_is_omap24xx()) {
host->iclk = clk_get(&pdev->dev, "mmc_ick");
if (IS_ERR(host->iclk))
goto out;
goto err_free_mmc_host;
clk_enable(host->iclk);
}

Expand All @@ -1069,7 +1073,7 @@ static int __init mmc_omap_probe(struct platform_device *pdev)

if (IS_ERR(host->fclk)) {
ret = PTR_ERR(host->fclk);
goto out;
goto err_free_iclk;
}

/* REVISIT:
Expand All @@ -1082,7 +1086,7 @@ static int __init mmc_omap_probe(struct platform_device *pdev)
host->use_dma = 1;
host->dma_ch = -1;

host->irq = pdev->resource[1].start;
host->irq = irq;
host->phys_base = host->mem_res->start;
host->virt_base = (void __iomem *) IO_ADDRESS(host->phys_base);

Expand All @@ -1108,20 +1112,18 @@ static int __init mmc_omap_probe(struct platform_device *pdev)
if ((ret = omap_request_gpio(host->power_pin)) != 0) {
dev_err(mmc_dev(host->mmc),
"Unable to get GPIO pin for MMC power\n");
goto out;
goto err_free_fclk;
}
omap_set_gpio_direction(host->power_pin, 0);
}

ret = request_irq(host->irq, mmc_omap_irq, 0, DRIVER_NAME, host);
if (ret)
goto out;
goto err_free_power_gpio;

host->dev = &pdev->dev;
platform_set_drvdata(pdev, host);

mmc_add_host(mmc);

if (host->switch_pin >= 0) {
INIT_WORK(&host->switch_work, mmc_omap_switch_handler, host);
init_timer(&host->switch_timer);
Expand Down Expand Up @@ -1159,10 +1161,11 @@ static int __init mmc_omap_probe(struct platform_device *pdev)
schedule_work(&host->switch_work);
}

no_switch:
mmc_add_host(mmc);

return 0;

out:
no_switch:
/* FIXME: Free other resources too. */
if (host) {
if (host->iclk && !IS_ERR(host->iclk))
Expand All @@ -1171,6 +1174,20 @@ static int __init mmc_omap_probe(struct platform_device *pdev)
clk_put(host->fclk);
mmc_free_host(host->mmc);
}
err_free_power_gpio:
if (host->power_pin >= 0)
omap_free_gpio(host->power_pin);
err_free_fclk:
clk_put(host->fclk);
err_free_iclk:
if (host->iclk != NULL) {
clk_disable(host->iclk);
clk_put(host->iclk);
}
err_free_mmc_host:
mmc_free_host(host->mmc);
err_free_mem_region:
release_mem_region(res->start, res->end - res->start + 1);
return ret;
}

Expand All @@ -1180,30 +1197,31 @@ static int mmc_omap_remove(struct platform_device *pdev)

platform_set_drvdata(pdev, NULL);

if (host) {
mmc_remove_host(host->mmc);
free_irq(host->irq, host);

if (host->power_pin >= 0)
omap_free_gpio(host->power_pin);
if (host->switch_pin >= 0) {
device_remove_file(&pdev->dev, &dev_attr_enable_poll);
device_remove_file(&pdev->dev, &dev_attr_cover_switch);
free_irq(OMAP_GPIO_IRQ(host->switch_pin), host);
omap_free_gpio(host->switch_pin);
host->switch_pin = -1;
del_timer_sync(&host->switch_timer);
flush_scheduled_work();
}
if (host->iclk && !IS_ERR(host->iclk))
clk_put(host->iclk);
if (host->fclk && !IS_ERR(host->fclk))
clk_put(host->fclk);
mmc_free_host(host->mmc);
BUG_ON(host == NULL);

mmc_remove_host(host->mmc);
free_irq(host->irq, host);

if (host->power_pin >= 0)
omap_free_gpio(host->power_pin);
if (host->switch_pin >= 0) {
device_remove_file(&pdev->dev, &dev_attr_enable_poll);
device_remove_file(&pdev->dev, &dev_attr_cover_switch);
free_irq(OMAP_GPIO_IRQ(host->switch_pin), host);
omap_free_gpio(host->switch_pin);
host->switch_pin = -1;
del_timer_sync(&host->switch_timer);
flush_scheduled_work();
}
if (host->iclk && !IS_ERR(host->iclk))
clk_put(host->iclk);
if (host->fclk && !IS_ERR(host->fclk))
clk_put(host->fclk);

release_mem_region(pdev->resource[0].start,
pdev->resource[0].end - pdev->resource[0].start + 1);
pdev->resource[0].end - pdev->resource[0].start + 1);

mmc_free_host(host->mmc);

return 0;
}
Expand Down

0 comments on commit 81ca703

Please sign in to comment.