summaryrefslogtreecommitdiff
path: root/drivers/mmc
diff options
context:
space:
mode:
authorGreg Meiste <w30289@motorola.com>2011-06-09 10:37:34 -0700
committerTodd Poynor <toddpoynor@google.com>2011-06-09 15:29:24 -0700
commitaff0e8a8fe0e05b33785f2d0fd19f1e108c41142 (patch)
treebe88f02f284dad28366b4a633705a0de6a57cf16 /drivers/mmc
parent64434eca54499db77943c59621d6413cfacc1654 (diff)
mmc: host: sdhci: Support runtime enable/disable of clock
Currently the SD card clock is running any time the AP is not in LP0. This patch allows the clock to only be enabled when the card is being accessed. Based on an nVidia patch: http://nv-tegra.nvidia.com/gitweb/?p=linux-2.6.git;a=commit;h=8c0f23b7e65ebdb6d1c160517e9ba509b16ec83f Conflicts: drivers/mmc/host/sdhci.c Change-Id: Id188a783ca9ce7046bf2ca526cafcd91a6fab507 Signed-off-by: Greg Meiste <w30289@motorola.com> Signed-off-by: Todd Poynor <toddpoynor@google.com>
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/host/sdhci.c34
-rw-r--r--drivers/mmc/host/sdhci.h2
2 files changed, 36 insertions, 0 deletions
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index f7695c4c169e..52718cf13e56 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1223,6 +1223,31 @@ static int sdhci_get_ro(struct mmc_host *mmc)
return !(present & SDHCI_WRITE_PROTECT);
}
+static int sdhci_enable(struct mmc_host *mmc)
+{
+ struct sdhci_host *host = mmc_priv(mmc);
+
+ if (!mmc->card || mmc->card->type == MMC_TYPE_SDIO)
+ return 0;
+
+ if (mmc->ios.clock)
+ sdhci_set_clock(host, mmc->ios.clock);
+
+ return 0;
+}
+
+static int sdhci_disable(struct mmc_host *mmc, int lazy)
+{
+ struct sdhci_host *host = mmc_priv(mmc);
+
+ if (!mmc->card || mmc->card->type == MMC_TYPE_SDIO)
+ return 0;
+
+ sdhci_set_clock(host, 0);
+
+ return 0;
+}
+
static void sdhci_enable_sdio_irq(struct mmc_host *mmc, int enable)
{
struct sdhci_host *host;
@@ -1249,6 +1274,8 @@ static const struct mmc_host_ops sdhci_ops = {
.request = sdhci_request,
.set_ios = sdhci_set_ios,
.get_ro = sdhci_get_ro,
+ .enable = sdhci_enable,
+ .disable = sdhci_disable,
.enable_sdio_irq = sdhci_enable_sdio_irq,
};
@@ -1829,6 +1856,13 @@ int sdhci_add_host(struct sdhci_host *host)
if (host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION)
mmc->caps |= MMC_CAP_NEEDS_POLL;
+ if (host->quirks & SDHCI_QUIRK_RUNTIME_DISABLE) {
+ mmc->caps |= MMC_CAP_DISABLE;
+ mmc_set_disable_delay(mmc, 50);
+ }
+
+ mmc->caps |= MMC_CAP_ERASE;
+
mmc->ocr_avail = 0;
if (caps & SDHCI_CAN_VDD_330)
mmc->ocr_avail |= MMC_VDD_32_33|MMC_VDD_33_34;
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index e866164c1413..ee99628635b8 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -263,6 +263,8 @@ struct sdhci_host {
#define SDHCI_QUIRK_NO_SDIO_IRQ (1LL<<36)
/* Controller should only use high-speed mode */
#define SDHCI_QUIRK_FORCE_HIGH_SPEED_MODE (1LL<<37)
+/* Controller allows runtime enable / disable */
+#define SDHCI_QUIRK_RUNTIME_DISABLE (1LL<<38)
int irq; /* Device IRQ */
void __iomem * ioaddr; /* Mapped address */