summaryrefslogtreecommitdiff
path: root/drivers/mmc/host/sdhci-tegra.c
diff options
context:
space:
mode:
authorPavan Kunapuli <pkunapuli@nvidia.com>2011-10-13 19:47:14 +0530
committerDan Willemsen <dwillemsen@nvidia.com>2011-11-30 21:49:27 -0800
commit2c5bc258a3f3bc3204dfe8690833e04c9dbce550 (patch)
tree8bf481283eee5d3e05bc1af8fd48c4e6837af2ca /drivers/mmc/host/sdhci-tegra.c
parent2944db5f3707d9176da44c3bf762e4ce7b0a636f (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.c27
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;