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

Commit ae0866ba authored by Sahitya Tummala's avatar Sahitya Tummala
Browse files

mmc: sdhci-msm: Fix issue with 1.8v switch sequence in 3.10 kernel



The SD3.0 voltage switch sequence to 1.8v would involve stopping the
SDCLK before changing the voltage level and with recent changes in 3.10
kernel, the peripheral clocks are also getting disabled instead of
just stopping the clock to the card. This patch makes sure this doesn't
happen by marking the flag card_clock_off in struct mmc_host before
starting the voltage switch sequence and checking it in host controller
driver.

Change-Id: If62378ba1dd369e69524365a4421d57317c22ca2
Signed-off-by: default avatarSahitya Tummala <stummala@codeaurora.org>
parent b3f49348
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -1887,6 +1887,7 @@ int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage)
	 * During a signal voltage level switch, the clock must be gated
	 * for 5 ms according to the SD spec
	 */
	host->card_clock_off = true;
	clock = host->ios.clock;
	host->ios.clock = 0;
	mmc_set_ios(host);
@@ -1897,6 +1898,9 @@ int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage)
		 * sent CMD11, so a power cycle is required anyway
		 */
		err = -EAGAIN;
		host->ios.clock = clock;
		mmc_set_ios(host);
		host->card_clock_off = false;
		goto power_cycle;
	}

@@ -1905,6 +1909,7 @@ int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage)
	host->ios.clock = clock;
	mmc_set_ios(host);

	host->card_clock_off = false;
	/* Wait for at least 1 ms according to spec */
	mmc_delay(1);

+10 −2
Original line number Diff line number Diff line
@@ -2378,10 +2378,18 @@ static int sdhci_msm_prepare_clocks(struct sdhci_host *host, bool enable)
		mb();

	} else if (!enable && atomic_read(&msm_host->clks_on)) {
		pr_debug("%s: request to disable clocks\n",
				mmc_hostname(host->mmc));
		sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
		mb();
		/*
		 * During 1.8V signal switching the clock source must
		 * still be ON as it requires accessing SDHC
		 * registers (SDHCi host control2 register bit 3 must
		 * be written and polled after stopping the SDCLK).
		 */
		if (host->mmc->card_clock_off)
			return 0;
		pr_debug("%s: request to disable clocks\n",
				mmc_hostname(host->mmc));
		if (!IS_ERR_OR_NULL(msm_host->sleep_clk))
			clk_disable_unprepare(msm_host->sleep_clk);
		if (!IS_ERR_OR_NULL(msm_host->ff_clk))
+5 −0
Original line number Diff line number Diff line
@@ -448,6 +448,11 @@ struct mmc_host {
		enum mmc_load	state;
	} clk_scaling;
	enum dev_state dev_status;
	/*
	 * Set to 1 to just stop the SDCLK to the card without
	 * actually disabling the clock from it's source.
	 */
	bool			card_clock_off;
	unsigned long		private[0] ____cacheline_aligned;
};