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

Commit 2bec0893 authored by Adrian Hunter's avatar Adrian Hunter Committed by Linus Torvalds
Browse files

omap_hsmmc: ensure all clock enables and disables are paired



[madhu.cr@ti.com: fix for the db clock failure message]
Signed-off-by: default avatarAdrian Hunter <adrian.hunter@nokia.com>
Acked-by: default avatarMatt Fleming <matt@console-pimps.org>
Cc: Ian Molton <ian@mnementh.co.uk>
Cc: "Roberto A. Foglietta" <roberto.foglietta@gmail.com>
Cc: Jarkko Lavinen <jarkko.lavinen@nokia.com>
Cc: Denis Karpov <ext-denis.2.karpov@nokia.com>
Cc: Pierre Ossman <pierre@ossman.eu>
Cc: Philip Langdale <philipl@overt.org>
Cc: "Madhusudhan" <madhu.cr@ti.com>
Cc: <linux-mmc@vger.kernel.org>
Signed-off-by: default avatarMadhusudhan Chikkature <madhu.cr@ti.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent b62f6228
Loading
Loading
Loading
Loading
+33 −27
Original line number Diff line number Diff line
@@ -162,7 +162,7 @@ struct omap_hsmmc_host {
	int			use_dma, dma_ch;
	int			dma_line_tx, dma_line_rx;
	int			slot_id;
	int			dbclk_enabled;
	int			got_dbclk;
	int			response_busy;
	int			context_loss;
	int			dpm_state;
@@ -742,22 +742,24 @@ static int omap_hsmmc_switch_opcond(struct omap_hsmmc_host *host, int vdd)
	/* Disable the clocks */
	clk_disable(host->fclk);
	clk_disable(host->iclk);
	if (host->got_dbclk)
		clk_disable(host->dbclk);

	/* Turn the power off */
	ret = mmc_slot(host).set_power(host->dev, host->slot_id, 0, 0);
	if (ret != 0)
		goto err;

	/* Turn the power ON with given VDD 1.8 or 3.0v */
	ret = mmc_slot(host).set_power(host->dev, host->slot_id, 1, vdd);
	if (ret != 0)
		goto err;

	clk_enable(host->fclk);
	if (!ret)
		ret = mmc_slot(host).set_power(host->dev, host->slot_id, 1,
					       vdd);
	clk_enable(host->iclk);
	clk_enable(host->fclk);
	if (host->got_dbclk)
		clk_enable(host->dbclk);

	if (ret != 0)
		goto err;

	OMAP_HSMMC_WRITE(host->base, HCTL,
		OMAP_HSMMC_READ(host->base, HCTL) & SDVSCLR);
	reg_val = OMAP_HSMMC_READ(host->base, HCTL);
@@ -1695,18 +1697,22 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev)
		goto err1;
	}

	if (cpu_is_omap2430()) {
		host->dbclk = clk_get(&pdev->dev, "mmchsdb_fck");
		/*
		 * MMC can still work without debounce clock.
		 */
		if (IS_ERR(host->dbclk))
		dev_warn(mmc_dev(host->mmc), "Failed to get debounce clock\n");
			dev_warn(mmc_dev(host->mmc),
				"Failed to get debounce clock\n");
		else
			host->got_dbclk = 1;

		if (host->got_dbclk)
			if (clk_enable(host->dbclk) != 0)
				dev_dbg(mmc_dev(host->mmc), "Enabling debounce"
							" clk failed\n");
		else
			host->dbclk_enabled = 1;
	}

	/* Since we do only SG emulation, we can have as many segs
	 * as we want. */
@@ -1820,7 +1826,7 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev)
	clk_disable(host->iclk);
	clk_put(host->fclk);
	clk_put(host->iclk);
	if (host->dbclk_enabled) {
	if (host->got_dbclk) {
		clk_disable(host->dbclk);
		clk_put(host->dbclk);
	}
@@ -1854,7 +1860,7 @@ static int omap_hsmmc_remove(struct platform_device *pdev)
		clk_disable(host->iclk);
		clk_put(host->fclk);
		clk_put(host->iclk);
		if (host->dbclk_enabled) {
		if (host->got_dbclk) {
			clk_disable(host->dbclk);
			clk_put(host->dbclk);
		}
@@ -1905,6 +1911,7 @@ static int omap_hsmmc_suspend(struct platform_device *pdev, pm_message_t state)
				OMAP_HSMMC_READ(host->base, HCTL) & ~SDBP);
			mmc_host_disable(host->mmc);
			clk_disable(host->iclk);
			if (host->got_dbclk)
				clk_disable(host->dbclk);
		} else {
			host->suspended = 0;
@@ -1936,15 +1943,14 @@ static int omap_hsmmc_resume(struct platform_device *pdev)
		if (ret)
			goto clk_en_err;

		if (clk_enable(host->dbclk) != 0)
			dev_dbg(mmc_dev(host->mmc),
					"Enabling debounce clk failed\n");

		if (mmc_host_enable(host->mmc) != 0) {
			clk_disable(host->iclk);
			goto clk_en_err;
		}

		if (host->got_dbclk)
			clk_enable(host->dbclk);

		omap_hsmmc_conf_bus_power(host);

		if (host->pdata->resume) {