diff options
author | Ken Chang <kenc@nvidia.com> | 2011-03-16 12:55:15 +0800 |
---|---|---|
committer | Varun Colbert <vcolbert@nvidia.com> | 2011-03-17 21:26:30 -0800 |
commit | 8c0f23b7e65ebdb6d1c160517e9ba509b16ec83f (patch) | |
tree | 766e2b279efb1e0f4a13796fe50e52d68069fc41 /drivers | |
parent | 1736107645aad0d0f094eeb10948d4eb489d1d59 (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.c | 3 | ||||
-rw-r--r-- | drivers/mmc/host/sdhci.c | 30 | ||||
-rw-r--r-- | drivers/mmc/host/sdhci.h | 2 |
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 */ |