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

Commit eb5c20de authored by Adrian Hunter's avatar Adrian Hunter Committed by Ulf Hansson
Browse files

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: default avatarAdrian Hunter <adrian.hunter@intel.com>
Signed-off-by: default avatarUlf Hansson <ulf.hansson@linaro.org>
parent d310ae49
Loading
Loading
Loading
Loading
+27 −9
Original line number Diff line number Diff line
@@ -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;
}