diff options
-rw-r--r-- | drivers/mmc/host/sdhci.c | 26 | ||||
-rw-r--r-- | drivers/mmc/host/sdhci.h | 2 |
2 files changed, 27 insertions, 1 deletions
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 70001ecb6ebe..c86c14af479f 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/dma-mapping.h> | 19 | #include <linux/dma-mapping.h> |
20 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
21 | #include <linux/scatterlist.h> | 21 | #include <linux/scatterlist.h> |
22 | #include <linux/regulator/consumer.h> | ||
22 | 23 | ||
23 | #include <linux/leds.h> | 24 | #include <linux/leds.h> |
24 | 25 | ||
@@ -1608,7 +1609,10 @@ int sdhci_suspend_host(struct sdhci_host *host, pm_message_t state) | |||
1608 | 1609 | ||
1609 | free_irq(host->irq, host); | 1610 | free_irq(host->irq, host); |
1610 | 1611 | ||
1611 | return 0; | 1612 | if (host->vmmc) |
1613 | ret = regulator_disable(host->vmmc); | ||
1614 | |||
1615 | return ret; | ||
1612 | } | 1616 | } |
1613 | 1617 | ||
1614 | EXPORT_SYMBOL_GPL(sdhci_suspend_host); | 1618 | EXPORT_SYMBOL_GPL(sdhci_suspend_host); |
@@ -1617,6 +1621,13 @@ int sdhci_resume_host(struct sdhci_host *host) | |||
1617 | { | 1621 | { |
1618 | int ret; | 1622 | int ret; |
1619 | 1623 | ||
1624 | if (host->vmmc) { | ||
1625 | int ret = regulator_enable(host->vmmc); | ||
1626 | if (ret) | ||
1627 | return ret; | ||
1628 | } | ||
1629 | |||
1630 | |||
1620 | if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) { | 1631 | if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) { |
1621 | if (host->ops->enable_dma) | 1632 | if (host->ops->enable_dma) |
1622 | host->ops->enable_dma(host); | 1633 | host->ops->enable_dma(host); |
@@ -1889,6 +1900,14 @@ int sdhci_add_host(struct sdhci_host *host) | |||
1889 | if (ret) | 1900 | if (ret) |
1890 | goto untasklet; | 1901 | goto untasklet; |
1891 | 1902 | ||
1903 | host->vmmc = regulator_get(mmc_dev(mmc), "vmmc"); | ||
1904 | if (IS_ERR(host->vmmc)) { | ||
1905 | printk(KERN_INFO "%s: no vmmc regulator found\n", mmc_hostname(mmc)); | ||
1906 | host->vmmc = NULL; | ||
1907 | } else { | ||
1908 | regulator_enable(host->vmmc); | ||
1909 | } | ||
1910 | |||
1892 | sdhci_init(host, 0); | 1911 | sdhci_init(host, 0); |
1893 | 1912 | ||
1894 | #ifdef CONFIG_MMC_DEBUG | 1913 | #ifdef CONFIG_MMC_DEBUG |
@@ -1973,6 +1992,11 @@ void sdhci_remove_host(struct sdhci_host *host, int dead) | |||
1973 | tasklet_kill(&host->card_tasklet); | 1992 | tasklet_kill(&host->card_tasklet); |
1974 | tasklet_kill(&host->finish_tasklet); | 1993 | tasklet_kill(&host->finish_tasklet); |
1975 | 1994 | ||
1995 | if (host->vmmc) { | ||
1996 | regulator_disable(host->vmmc); | ||
1997 | regulator_put(host->vmmc); | ||
1998 | } | ||
1999 | |||
1976 | kfree(host->adma_desc); | 2000 | kfree(host->adma_desc); |
1977 | kfree(host->align_buffer); | 2001 | kfree(host->align_buffer); |
1978 | 2002 | ||
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index c98315c197ed..ff070a309f8d 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h | |||
@@ -249,6 +249,8 @@ struct sdhci_host { | |||
249 | 249 | ||
250 | const struct sdhci_ops *ops; /* Low level hw interface */ | 250 | const struct sdhci_ops *ops; /* Low level hw interface */ |
251 | 251 | ||
252 | struct regulator *vmmc; /* Power regulator */ | ||
253 | |||
252 | /* Internal data */ | 254 | /* Internal data */ |
253 | struct mmc_host *mmc; /* MMC structure */ | 255 | struct mmc_host *mmc; /* MMC structure */ |
254 | u64 dma_mask; /* custom DMA mask */ | 256 | u64 dma_mask; /* custom DMA mask */ |