summaryrefslogtreecommitdiff
path: root/drivers/mmc
diff options
context:
space:
mode:
authorTodd Poynor <toddpoynor@google.com>2010-10-11 15:31:42 -0700
committerTodd Poynor <toddpoynor@google.com>2010-11-08 15:37:55 -0800
commitb449ac9b84009fd7ac8ac9593032a14eae165d27 (patch)
treebe4346c94a3e7ab05bb24b75f9c1a4704425637b /drivers/mmc
parent260a918374de22dca1156367fdf739426192463a (diff)
tegra sdhci: Enable/disable SDCLK source in set_clock host_op
Now with 100% more LP0 suspend support. sdhci_resume_host accesses the SDHCI controller, so enable the sdmmc<n> clock at resume, and let the MMC card layer tell us (later on) whether SDCLK is needed or not. Change-Id: Ia66e54e93f607d03053315fdc3b9a0e9bea29b68 Signed-off-by: Todd Poynor <toddpoynor@google.com>
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/host/sdhci-tegra.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
index 361c8e780683..19f522d3a59f 100644
--- a/drivers/mmc/host/sdhci-tegra.c
+++ b/drivers/mmc/host/sdhci-tegra.c
@@ -30,9 +30,12 @@
#define DRIVER_NAME "sdhci-tegra"
+#define SDHCI_VENDOR_CLOCK_CNTRL 0x100
+
struct tegra_sdhci_host {
struct sdhci_host *sdhci;
struct clk *clk;
+ int clk_enabled;
};
static irqreturn_t carddetect_irq(int irq, void *data)
@@ -48,8 +51,31 @@ static int tegra_sdhci_enable_dma(struct sdhci_host *host)
return 0;
}
+static void tegra_sdhci_enable_clock(struct tegra_sdhci_host *host, int enable)
+{
+ if (enable && !host->clk_enabled) {
+ clk_enable(host->clk);
+ sdhci_writeb(host->sdhci, 1, SDHCI_VENDOR_CLOCK_CNTRL);
+ host->clk_enabled = 1;
+ } else if (!enable && host->clk_enabled) {
+ sdhci_writeb(host->sdhci, 0, SDHCI_VENDOR_CLOCK_CNTRL);
+ clk_disable(host->clk);
+ host->clk_enabled = 0;
+ }
+}
+
+static void tegra_sdhci_set_clock(struct sdhci_host *sdhci, unsigned int clock)
+{
+ struct tegra_sdhci_host *host = sdhci_priv(sdhci);
+ pr_info("tegra sdhci clock %s %u enabled=%d\n",
+ mmc_hostname(sdhci->mmc), clock, host->clk_enabled);
+
+ tegra_sdhci_enable_clock(host, clock);
+}
+
static struct sdhci_ops tegra_sdhci_ops = {
.enable_dma = tegra_sdhci_enable_dma,
+ .set_clock = tegra_sdhci_set_clock,
};
static int __devinit tegra_sdhci_probe(struct platform_device *pdev)
@@ -97,6 +123,7 @@ static int __devinit tegra_sdhci_probe(struct platform_device *pdev)
if (rc != 0)
goto err_clkput;
+ host->clk_enabled = 1;
sdhci->hw_name = "tegra";
sdhci->ops = &tegra_sdhci_ops;
sdhci->irq = irq;
@@ -187,6 +214,7 @@ static int tegra_sdhci_resume(struct platform_device *pdev)
struct tegra_sdhci_host *host = platform_get_drvdata(pdev);
int ret;
+ tegra_sdhci_enable_clock(host, 1);
ret = sdhci_resume_host(host->sdhci);
if (ret)
pr_err("%s: failed, error = %d\n", __func__, ret);