diff options
author | Linus Walleij <linus.walleij@stericsson.com> | 2010-09-29 01:08:27 -0400 |
---|---|---|
committer | Chris Ball <cjb@laptop.org> | 2010-10-23 09:11:16 -0400 |
commit | 99fc5131018cbdc3cf42ce09fb394a4e8b053c74 (patch) | |
tree | 68638188b665af5add8d885b3e22a6edd537de7e /drivers/mmc/host/mmci.c | |
parent | 4d0b8611cd4da64f075b8e07a126f0eb498fb153 (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.c | 28 |
1 files changed, 18 insertions, 10 deletions
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 5f2e72d38b5d..87b4fc6c98c2 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) | |||
523 | struct mmci_host *host = mmc_priv(mmc); | 523 | struct mmci_host *host = mmc_priv(mmc); |
524 | u32 pwr = 0; | 524 | u32 pwr = 0; |
525 | unsigned long flags; | 525 | unsigned long flags; |
526 | int ret; | ||
526 | 527 | ||
527 | switch (ios->power_mode) { | 528 | switch (ios->power_mode) { |
528 | case MMC_POWER_OFF: | 529 | case MMC_POWER_OFF: |
529 | if(host->vcc && | 530 | if (host->vcc) |
530 | regulator_is_enabled(host->vcc)) | 531 | ret = mmc_regulator_set_ocr(mmc, host->vcc, 0); |
531 | regulator_disable(host->vcc); | ||
532 | break; | 532 | break; |
533 | case MMC_POWER_UP: | 533 | case MMC_POWER_UP: |
534 | #ifdef CONFIG_REGULATOR | 534 | if (host->vcc) { |
535 | if (host->vcc) | 535 | ret = mmc_regulator_set_ocr(mmc, host->vcc, ios->vdd); |
536 | /* This implicitly enables the regulator */ | 536 | if (ret) { |
537 | mmc_regulator_set_ocr(host->vcc, ios->vdd); | 537 | dev_err(mmc_dev(mmc), "unable to set OCR\n"); |
538 | #endif | 538 | /* |
539 | * The .set_ios() function in the mmc_host_ops | ||
540 | * struct return void, and failing to set the | ||
541 | * power should be rare so we print an error | ||
542 | * and return here. | ||
543 | */ | ||
544 | return; | ||
545 | } | ||
546 | } | ||
539 | if (host->plat->vdd_handler) | 547 | if (host->plat->vdd_handler) |
540 | pwr |= host->plat->vdd_handler(mmc_dev(mmc), ios->vdd, | 548 | pwr |= host->plat->vdd_handler(mmc_dev(mmc), ios->vdd, |
541 | ios->power_mode); | 549 | ios->power_mode); |
@@ -869,8 +877,8 @@ static int __devexit mmci_remove(struct amba_device *dev) | |||
869 | clk_disable(host->clk); | 877 | clk_disable(host->clk); |
870 | clk_put(host->clk); | 878 | clk_put(host->clk); |
871 | 879 | ||
872 | if (regulator_is_enabled(host->vcc)) | 880 | if (host->vcc) |
873 | regulator_disable(host->vcc); | 881 | mmc_regulator_set_ocr(mmc, host->vcc, 0); |
874 | regulator_put(host->vcc); | 882 | regulator_put(host->vcc); |
875 | 883 | ||
876 | mmc_free_host(mmc); | 884 | mmc_free_host(mmc); |