diff options
author | Adrian Hunter | 2016-04-12 14:25:08 +0300 |
---|---|---|
committer | Ulf Hansson | 2016-05-02 10:33:29 +0200 |
commit | eb5c20de351867120c8dfb6d523d5795a3125b02 (patch) | |
tree | 154104ac4d4d79835ab8b7006c84bc861e9dddae /drivers/mmc | |
parent | d310ae4936ccf1186851692c511483c794dd7701 (diff) |
mmc: sdhci: Fix error paths in sdhci_add_host()
Some error paths in sdhci_add_host() simply returned without
cleaning up. Also the return value from mmc_add_host()
was not being checked.
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Diffstat (limited to 'drivers/mmc')
-rw-r--r-- | drivers/mmc/host/sdhci.c | 36 |
1 files changed, 27 insertions, 9 deletions
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 73edf44ad1ac..734f3773478e 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -2965,7 +2965,8 @@ int sdhci_add_host(struct sdhci_host *host) if (!host->ops->get_max_clock) { pr_err("%s: Hardware doesn't specify base clock frequency.\n", mmc_hostname(mmc)); - return -ENODEV; + ret = -ENODEV; + goto undma; } host->max_clk = host->ops->get_max_clock(host); } @@ -3015,7 +3016,8 @@ int sdhci_add_host(struct sdhci_host *host) } else { pr_err("%s: Hardware doesn't specify timeout clock frequency.\n", mmc_hostname(mmc)); - return -ENODEV; + ret = -ENODEV; + goto undma; } } @@ -3069,8 +3071,9 @@ int sdhci_add_host(struct sdhci_host *host) mmc->caps |= MMC_CAP_NEEDS_POLL; /* If there are external regulators, get them */ - if (mmc_regulator_get_supply(mmc) == -EPROBE_DEFER) - return -EPROBE_DEFER; + ret = mmc_regulator_get_supply(mmc); + if (ret == -EPROBE_DEFER) + goto undma; /* If vqmmc regulator and no 1.8V signalling, then there's no UHS */ if (!IS_ERR(mmc->supply.vqmmc)) { @@ -3227,7 +3230,8 @@ int sdhci_add_host(struct sdhci_host *host) if (mmc->ocr_avail == 0) { pr_err("%s: Hardware doesn't report any support voltages.\n", mmc_hostname(mmc)); - return -ENODEV; + ret = -ENODEV; + goto unreg; } spin_lock_init(&host->lock); @@ -3323,13 +3327,15 @@ int sdhci_add_host(struct sdhci_host *host) if (ret) { pr_err("%s: Failed to register LED device: %d\n", mmc_hostname(mmc), ret); - goto reset; + goto unirq; } #endif mmiowb(); - mmc_add_host(mmc); + ret = mmc_add_host(mmc); + if (ret) + goto unled; pr_info("%s: SDHCI controller on %s [%s] using %s\n", mmc_hostname(mmc), host->hw_name, dev_name(mmc_dev(mmc)), @@ -3341,15 +3347,27 @@ int sdhci_add_host(struct sdhci_host *host) return 0; +unled: #ifdef SDHCI_USE_LEDS_CLASS -reset: + led_classdev_unregister(&host->led); +unirq: +#endif sdhci_do_reset(host, SDHCI_RESET_ALL); sdhci_writel(host, 0, SDHCI_INT_ENABLE); sdhci_writel(host, 0, SDHCI_SIGNAL_ENABLE); free_irq(host->irq, host); -#endif untasklet: tasklet_kill(&host->finish_tasklet); +unreg: + if (!IS_ERR(mmc->supply.vqmmc)) + regulator_disable(mmc->supply.vqmmc); +undma: + if (host->align_buffer) + dma_free_coherent(mmc_dev(mmc), host->align_buffer_sz + + host->adma_table_sz, host->align_buffer, + host->align_addr); + host->adma_table = NULL; + host->align_buffer = NULL; return ret; } |