summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authornaveenk <naveenk@nvidia.com>2011-10-18 16:16:39 +0530
committerSimone Willett <swillett@nvidia.com>2011-10-18 16:24:31 -0700
commit6332e1816622df552b06dcc6408974cc795c29a9 (patch)
treebfae7bda3f3893e43a6f6c660a874800d558fd34 /drivers
parentb467e319368370c9af13982c99a621ef6aadaa5e (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.c60
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;
}