summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorKen Chang <kenc@nvidia.com>2011-03-16 12:55:15 +0800
committerVarun Colbert <vcolbert@nvidia.com>2011-03-17 21:26:30 -0800
commit8c0f23b7e65ebdb6d1c160517e9ba509b16ec83f (patch)
tree766e2b279efb1e0f4a13796fe50e52d68069fc41 /drivers
parent1736107645aad0d0f094eeb10948d4eb489d1d59 (diff)
mmc: host: support runtime enable/disable SDCLK
Implement functions needed in struct mmc_host_ops to support enable/disable SDCLK dynamically. Add SDHCI_QUIRK_RUNTIME_DISABLE to switch on/off this feature. Bug 800655 Change-Id: I4c71ca4beb56df020381236ca8ec949647a0d333 Reviewed-on: http://git-master/r/23125 Reviewed-by: Varun Colbert <vcolbert@nvidia.com> Tested-by: Varun Colbert <vcolbert@nvidia.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mmc/host/sdhci-tegra.c3
-rw-r--r--drivers/mmc/host/sdhci.c30
-rw-r--r--drivers/mmc/host/sdhci.h2
3 files changed, 34 insertions, 1 deletions
diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
index dcb5551bc267..3f54f759fe1c 100644
--- a/drivers/mmc/host/sdhci-tegra.c
+++ b/drivers/mmc/host/sdhci-tegra.c
@@ -150,7 +150,8 @@ static int __devinit tegra_sdhci_probe(struct platform_device *pdev)
SDHCI_QUIRK_NO_HISPD_BIT |
SDHCI_QUIRK_8_BIT_DATA |
SDHCI_QUIRK_NO_VERSION_REG |
- SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC;
+ SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC |
+ SDHCI_QUIRK_RUNTIME_DISABLE;
if (plat->force_hs != 0)
sdhci->quirks |= SDHCI_QUIRK_FORCE_HIGH_SPEED_MODE;
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 7577da76fbb2..d1180cc49bb8 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1261,10 +1261,37 @@ out:
spin_unlock_irqrestore(&host->lock, flags);
}
+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;
+}
+
+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 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,
};
@@ -1871,6 +1898,9 @@ 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->caps |= MMC_CAP_ERASE;
mmc->ocr_avail = 0;
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index e4d155912812..781cd2a3e95d 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -264,6 +264,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 */