Merge commit 'main-jb-2012.08.03-B4' into t114-0806
[linux-2.6.git] / drivers / mmc / host / sdhci.c
index de7cc6b..76499e0 100644 (file)
@@ -1979,19 +1979,13 @@ int sdhci_enable(struct mmc_host *mmc)
        struct sdhci_host *host = mmc_priv(mmc);
        u16 clk;
 
-       if (!mmc->card)
+       if (!mmc->card || mmc->card->type == MMC_TYPE_SDIO)
                return 0;
 
        if (mmc->ios.clock) {
-               if (mmc->card->type != MMC_TYPE_SDIO) {
-                       if (host->ops->set_clock)
-                               host->ops->set_clock(host, mmc->ios.clock);
-                       sdhci_set_clock(host, mmc->ios.clock);
-               } else {
-                       clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
-                       clk |= SDHCI_CLOCK_CARD_EN;
-                       sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
-               }
+               if (host->ops->set_clock)
+                       host->ops->set_clock(host, mmc->ios.clock);
+               sdhci_set_clock(host, mmc->ios.clock);
        }
 
        return 0;
@@ -2002,19 +1996,12 @@ int sdhci_disable(struct mmc_host *mmc, int lazy)
        struct sdhci_host *host = mmc_priv(mmc);
        u16 clk;
 
-       if (!mmc->card)
+       if (!mmc->card || mmc->card->type == MMC_TYPE_SDIO)
                return 0;
 
-       /* For SDIO cards, only disable the card clock. */
-       if (mmc->card->type != MMC_TYPE_SDIO) {
-               sdhci_set_clock(host, 0);
-               if (host->ops->set_clock)
-                       host->ops->set_clock(host, 0);
-       } else {
-               clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
-               clk &= ~SDHCI_CLOCK_CARD_EN;
-               sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
-       }
+       sdhci_set_clock(host, 0);
+       if (host->ops->set_clock)
+               host->ops->set_clock(host, 0);
 
        return 0;
 }
@@ -2496,7 +2483,16 @@ int sdhci_suspend_host(struct sdhci_host *host)
                host->flags &= ~SDHCI_NEEDS_RETUNING;
        }
 
-       if (mmc->card)
+       if (mmc->card) {
+               /*
+                * If eMMC cards are put in sleep state, Vccq can be disabled
+                * but Vcc would still be powered on. In resume, we only restore
+                * the controller context. So, set MMC_PM_KEEP_POWER flag.
+                */
+               if (mmc_card_can_sleep(mmc) &&
+                       !(mmc->caps & MMC_CAP2_NO_SLEEP_CMD))
+                       mmc->pm_flags = MMC_PM_KEEP_POWER;
+
                ret = mmc_suspend_host(host->mmc);
        if (ret) {
                if (has_tuning_timer) {