mmc: core: Improve support for deferred regulators
authorTim Kryger <tim.kryger@linaro.org>
Tue, 6 May 2014 22:57:01 +0000 (15:57 -0700)
committerChris Ball <chris@printf.net>
Mon, 12 May 2014 22:08:24 +0000 (18:08 -0400)
Callers of mmc_regulator_get_supply could benefit from knowing if either
of the regulators are present but not yet available.  Since callers do
not currently examine the return value, modify this function to return
zero or -EPROBE_DEFER if either regulator get returns the same.

Furthermore, since callers check vmmc/vqmmc using IS_ERR and can deal
with absent regulators, switch to devm_regulator_get_optional. This has
the added benefit of allowing this function to behave correctly even in
the !CONFIG_REGULATOR case such that the stub can be removed.

Signed-off-by: Tim Kryger <tim.kryger@linaro.org>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Chris Ball <chris@printf.net>
drivers/mmc/core/core.c
include/linux/mmc/host.h

index 02baa30653fa1a6a259b26f5f74878cd743dfb6a..7dc0c85fdb6067b980b7cfd636e4c23a98d1803c 100644 (file)
@@ -1314,31 +1314,38 @@ int mmc_regulator_set_ocr(struct mmc_host *mmc,
 }
 EXPORT_SYMBOL_GPL(mmc_regulator_set_ocr);
 
+#endif /* CONFIG_REGULATOR */
+
 int mmc_regulator_get_supply(struct mmc_host *mmc)
 {
        struct device *dev = mmc_dev(mmc);
-       struct regulator *supply;
        int ret;
 
-       supply = devm_regulator_get(dev, "vmmc");
-       mmc->supply.vmmc = supply;
+       mmc->supply.vmmc = devm_regulator_get_optional(dev, "vmmc");
        mmc->supply.vqmmc = devm_regulator_get_optional(dev, "vqmmc");
 
-       if (IS_ERR(supply))
-               return PTR_ERR(supply);
+       if (IS_ERR(mmc->supply.vmmc)) {
+               if (PTR_ERR(mmc->supply.vmmc) == -EPROBE_DEFER)
+                       return -EPROBE_DEFER;
+               dev_info(dev, "No vmmc regulator found\n");
+       } else {
+               ret = mmc_regulator_get_ocrmask(mmc->supply.vmmc);
+               if (ret > 0)
+                       mmc->ocr_avail = ret;
+               else
+                       dev_warn(dev, "Failed getting OCR mask: %d\n", ret);
+       }
 
-       ret = mmc_regulator_get_ocrmask(supply);
-       if (ret > 0)
-               mmc->ocr_avail = ret;
-       else
-               dev_warn(mmc_dev(mmc), "Failed getting OCR mask: %d\n", ret);
+       if (IS_ERR(mmc->supply.vqmmc)) {
+               if (PTR_ERR(mmc->supply.vqmmc) == -EPROBE_DEFER)
+                       return -EPROBE_DEFER;
+               dev_info(dev, "No vqmmc regulator found\n");
+       }
 
        return 0;
 }
 EXPORT_SYMBOL_GPL(mmc_regulator_get_supply);
 
-#endif /* CONFIG_REGULATOR */
-
 /*
  * Mask off any voltages we don't support and select
  * the lowest voltage
index 1830873742157011f59b427175cb6999e7009135..cd595275e11831d04bf770d4e8f920366926ffad 100644 (file)
@@ -402,7 +402,6 @@ int mmc_regulator_get_ocrmask(struct regulator *supply);
 int mmc_regulator_set_ocr(struct mmc_host *mmc,
                        struct regulator *supply,
                        unsigned short vdd_bit);
-int mmc_regulator_get_supply(struct mmc_host *mmc);
 #else
 static inline int mmc_regulator_get_ocrmask(struct regulator *supply)
 {
@@ -415,13 +414,10 @@ static inline int mmc_regulator_set_ocr(struct mmc_host *mmc,
 {
        return 0;
 }
-
-static inline int mmc_regulator_get_supply(struct mmc_host *mmc)
-{
-       return 0;
-}
 #endif
 
+int mmc_regulator_get_supply(struct mmc_host *mmc);
+
 int mmc_pm_notify(struct notifier_block *notify_block, unsigned long, void *);
 
 static inline int mmc_card_is_removable(struct mmc_host *host)