diff options
author | naveenk <naveenk@nvidia.com> | 2011-10-18 16:16:39 +0530 |
---|---|---|
committer | Simone Willett <swillett@nvidia.com> | 2011-10-18 16:24:31 -0700 |
commit | 6332e1816622df552b06dcc6408974cc795c29a9 (patch) | |
tree | bfae7bda3f3893e43a6f6c660a874800d558fd34 /drivers | |
parent | b467e319368370c9af13982c99a621ef6aadaa5e (diff) |
sdhci: tegra: Enabling power rails when card present
Enabling power rails when the card is present
which reduces power consumption
Bug 883197
Change-Id: I5ab6aa90d2fa752a7c91b3ec0db4400bb06ce842
Reviewed-on: http://git-master/r/58104
Reviewed-by: Simone Willett <swillett@nvidia.com>
Tested-by: Simone Willett <swillett@nvidia.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/mmc/host/sdhci-tegra.c | 60 |
1 files changed, 43 insertions, 17 deletions
diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c index 2f2928e53864..4f1c307d3054 100644 --- a/drivers/mmc/host/sdhci-tegra.c +++ b/drivers/mmc/host/sdhci-tegra.c @@ -73,6 +73,7 @@ struct tegra_sdhci_host { int cd_gpio_polarity; int wp_gpio; int wp_gpio_polarity; + int is_rail_enabled; unsigned int tap_delay; unsigned int max_clk; unsigned int clk_limit; @@ -90,6 +91,16 @@ static irqreturn_t carddetect_irq(int irq, void *data) host->card_present = (gpio_get_value(host->cd_gpio) == host->cd_gpio_polarity); + if(host->card_present){ + if(host->is_rail_enabled == 0){ + if (host->reg_vdd_slot) + regulator_enable(host->reg_vdd_slot); + if (host->reg_vddio) + regulator_enable(host->reg_vddio); + host->is_rail_enabled = 1; + } + } + tasklet_schedule(&sdhost->card_tasklet); return IRQ_HANDLED; }; @@ -363,6 +374,7 @@ static int __devinit tegra_sdhci_probe(struct platform_device *pdev) host->reg_vddio = NULL; } else { regulator_enable(host->reg_vddio); + host->is_rail_enabled = 1; } } } @@ -419,7 +431,7 @@ static int __devinit tegra_sdhci_probe(struct platform_device *pdev) host->card_present = 1; if (plat->cd_gpio != -1) { - rc = request_irq(gpio_to_irq(plat->cd_gpio), carddetect_irq, + rc = request_threaded_irq(gpio_to_irq(plat->cd_gpio), NULL, carddetect_irq, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, mmc_hostname(sdhci->mmc), sdhci); if (rc) @@ -427,6 +439,13 @@ static int __devinit tegra_sdhci_probe(struct platform_device *pdev) host->card_present = (gpio_get_value(plat->cd_gpio) == host->cd_gpio_polarity); + if(!host->card_present){ + if (host->reg_vddio) + regulator_disable(host->reg_vddio); + if (host->reg_vdd_slot) + regulator_disable(host->reg_vdd_slot); + host->is_rail_enabled = 0; + } } else if (plat->register_status_notify) { plat->register_status_notify( tegra_sdhci_status_notify_cb, sdhci); @@ -587,11 +606,13 @@ static int tegra_sdhci_suspend(struct platform_device *pdev, pm_message_t state) pr_err("%s: failed, error = %d\n", __func__, ret); tegra_sdhci_enable_clock(host, 0); - - if (host->reg_vddio) - ret = regulator_disable(host->reg_vddio); - if (host->reg_vdd_slot) - ret = regulator_disable(host->reg_vdd_slot); + if(host->is_rail_enabled == 1){ + if (host->reg_vddio) + ret = regulator_disable(host->reg_vddio); + if (host->reg_vdd_slot) + ret = regulator_disable(host->reg_vdd_slot); + host->is_rail_enabled = 0; + } return ret; } @@ -620,17 +641,6 @@ static int tegra_sdhci_resume(struct platform_device *pdev) return 0; } - if (host->reg_vdd_slot) - ret = regulator_enable(host->reg_vdd_slot); - if (host->reg_vddio) - ret = regulator_enable(host->reg_vddio); - - tegra_sdhci_enable_clock(host, SDHCI_TEGRA_MIN_CONTROLLER_CLOCK); - - ret = sdhci_resume_host(host->sdhci); - if (ret) - pr_err("%s: failed, error = %d\n", __func__, ret); - if (host->cd_gpio != -1) { int prev_card_present_stat = 0; @@ -642,6 +652,22 @@ static int tegra_sdhci_resume(struct platform_device *pdev) if (prev_card_present_stat != host->card_present) sdhci_card_detect_callback(host->sdhci); } + if(host->card_present){ + if(host->is_rail_enabled == 0){ + if (host->reg_vdd_slot) + ret = regulator_enable(host->reg_vdd_slot); + if (host->reg_vddio) + ret = regulator_enable(host->reg_vddio); + host->is_rail_enabled = 1; + } + } + + tegra_sdhci_enable_clock(host, SDHCI_TEGRA_MIN_CONTROLLER_CLOCK); + + ret = sdhci_resume_host(host->sdhci); + if (ret) + pr_err("%s: failed, error = %d\n", __func__, ret); + return ret; } |