summaryrefslogtreecommitdiffstats
path: root/drivers/mmc/host/mmci.c
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@stericsson.com>2010-09-29 01:08:27 -0400
committerChris Ball <cjb@laptop.org>2010-10-23 21:11:16 +0800
commit99fc5131018cbdc3cf42ce09fb394a4e8b053c74 (patch)
tree68638188b665af5add8d885b3e22a6edd537de7e /drivers/mmc/host/mmci.c
parent4d0b8611cd4da64f075b8e07a126f0eb498fb153 (diff)
mmc: Move regulator handling closer to core
After discovering a problem in regulator reference counting I took Mark Brown's advice to move the reference count into the MMC core by making the regulator status a member of struct mmc_host. I took this opportunity to also implement NULL versions of the regulator functions so as to rid the driver code from some ugly #ifdef CONFIG_REGULATOR clauses. Signed-off-by: Linus Walleij <linus.walleij@stericsson.com> Reviewed-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Cc: Liam Girdwood <lrg@slimlogic.co.uk> Cc: Tony Lindgren <tony@atomide.com> Cc: Adrian Hunter <adrian.hunter@nokia.com> Cc: Robert Jarzmik <robert.jarzmik@free.fr> Cc: Sundar Iyer <sundar.iyer@stericsson.com> Cc: Daniel Mack <daniel@caiaq.de> Cc: Pierre Ossman <pierre@ossman.eu> Cc: Matt Fleming <matt@console-pimps.org> Cc: David Brownell <dbrownell@users.sourceforge.net> Cc: Russell King <rmk+kernel@arm.linux.org.uk> Cc: Eric Miao <eric.y.miao@gmail.com> Cc: Cliff Brake <cbrake@bec-systems.com> Cc: Jarkko Lavinen <jarkko.lavinen@nokia.com> Cc: <linux-mmc@vger.kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Chris Ball <cjb@laptop.org>
Diffstat (limited to 'drivers/mmc/host/mmci.c')
-rw-r--r--drivers/mmc/host/mmci.c28
1 files changed, 18 insertions, 10 deletions
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 5f2e72d38b5..87b4fc6c98c 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -523,19 +523,27 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
struct mmci_host *host = mmc_priv(mmc);
u32 pwr = 0;
unsigned long flags;
+ int ret;
switch (ios->power_mode) {
case MMC_POWER_OFF:
- if(host->vcc &&
- regulator_is_enabled(host->vcc))
- regulator_disable(host->vcc);
+ if (host->vcc)
+ ret = mmc_regulator_set_ocr(mmc, host->vcc, 0);
break;
case MMC_POWER_UP:
-#ifdef CONFIG_REGULATOR
- if (host->vcc)
- /* This implicitly enables the regulator */
- mmc_regulator_set_ocr(host->vcc, ios->vdd);
-#endif
+ if (host->vcc) {
+ ret = mmc_regulator_set_ocr(mmc, host->vcc, ios->vdd);
+ if (ret) {
+ dev_err(mmc_dev(mmc), "unable to set OCR\n");
+ /*
+ * The .set_ios() function in the mmc_host_ops
+ * struct return void, and failing to set the
+ * power should be rare so we print an error
+ * and return here.
+ */
+ return;
+ }
+ }
if (host->plat->vdd_handler)
pwr |= host->plat->vdd_handler(mmc_dev(mmc), ios->vdd,
ios->power_mode);
@@ -869,8 +877,8 @@ static int __devexit mmci_remove(struct amba_device *dev)
clk_disable(host->clk);
clk_put(host->clk);
- if (regulator_is_enabled(host->vcc))
- regulator_disable(host->vcc);
+ if (host->vcc)
+ mmc_regulator_set_ocr(mmc, host->vcc, 0);
regulator_put(host->vcc);
mmc_free_host(mmc);