diff options
author | Pavan Kunapuli <pkunapuli@nvidia.com> | 2011-10-13 19:47:14 +0530 |
---|---|---|
committer | Dan Willemsen <dwillemsen@nvidia.com> | 2011-11-30 21:49:27 -0800 |
commit | 2c5bc258a3f3bc3204dfe8690833e04c9dbce550 (patch) | |
tree | 8bf481283eee5d3e05bc1af8fd48c4e6837af2ca /drivers/mmc/host/sdhci-tegra.c | |
parent | 2944db5f3707d9176da44c3bf762e4ce7b0a636f (diff) |
sdhci: tegra: Add context restore support for SDIO
Set MMC_CAP_SDIO_IRQ to use interrupts rather than
polling for SDIO function handling.
Set MMC_PM_KEEP_POWER for embedded SDIO devices.
Add controller reset and power on for devices with
MMC_PM_KEEP_POWER flag set.
Bug 883715
Change-Id: I35c98ba879b564752662f60365ee8a5e72d3a587
Reviewed-on: http://git-master/r/57869
Tested-by: Pavan Kunapuli <pkunapuli@nvidia.com>
Reviewed-by: Sachin Nikam <snikam@nvidia.com>
Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>
Rebase-Id: Rc95d4035ea4569cf1742d5785efff7df7ffa2ade
Diffstat (limited to 'drivers/mmc/host/sdhci-tegra.c')
-rw-r--r-- | drivers/mmc/host/sdhci-tegra.c | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c index 1b4739e64735..fba2d43fe589 100644 --- a/drivers/mmc/host/sdhci-tegra.c +++ b/drivers/mmc/host/sdhci-tegra.c @@ -305,6 +305,7 @@ static int tegra_sdhci_resume(struct sdhci_host *sdhci) { struct sdhci_pltfm_host *pltfm_host = sdhci_priv(sdhci); struct tegra_sdhci_host *tegra_host = pltfm_host->priv; + unsigned long timeout; /* Enable the power rails if any */ if (tegra_host->vdd_io_reg) @@ -315,6 +316,28 @@ static int tegra_sdhci_resume(struct sdhci_host *sdhci) /* Setting the min identification clock of freq 400KHz */ tegra_sdhci_set_clock(sdhci, 400000); + /* Reset the controller and power on if MMC_KEEP_POWER flag is set*/ + if (sdhci->mmc->pm_flags & MMC_PM_KEEP_POWER) { + sdhci_writeb(sdhci, SDHCI_RESET_ALL, SDHCI_SOFTWARE_RESET); + + /* Wait max 100 ms */ + timeout = 100; + + /* hw clears the bit when it's done */ + while (sdhci_readb(sdhci, SDHCI_SOFTWARE_RESET) & SDHCI_RESET_ALL) { + if (timeout == 0) { + printk(KERN_ERR "%s: Reset 0x%x never completed.\n", + mmc_hostname(sdhci->mmc), (int)SDHCI_RESET_ALL); + return -ETIMEDOUT; + } + timeout--; + mdelay(1); + } + + sdhci_writeb(sdhci, SDHCI_POWER_ON, SDHCI_POWER_CONTROL); + sdhci->pwr = 0; + } + return 0; } @@ -482,10 +505,14 @@ static int __devinit sdhci_tegra_probe(struct platform_device *pdev) host->mmc->caps |= MMC_CAP_ERASE; if (plat->is_8bit) host->mmc->caps |= MMC_CAP_8_BIT_DATA; + host->mmc->caps |= MMC_CAP_SDIO_IRQ; if (plat->mmc_data.built_in) { host->mmc->caps |= MMC_CAP_NONREMOVABLE; } + /* Do not turn OFF embedded sdio cards as it support Wake on Wireless */ + if (plat->mmc_data.embedded_sdio) + host->mmc->pm_flags = MMC_PM_KEEP_POWER; #ifdef CONFIG_ARCH_TEGRA_2x_SOC tegra_host->hw_ops = &tegra_2x_sdhci_ops; |