aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/host/dw_mmc.c
diff options
context:
space:
mode:
authorDoug Anderson <dianders@chromium.org>2013-06-07 13:28:29 -0400
committerChris Ball <cjb@laptop.org>2013-06-27 12:39:06 -0400
commit870556a3dfb16d004f8e09dd59a1eddc727fcf0c (patch)
tree54c95bbaea975ad8cc85137fb6d72ec8b8f1f12b /drivers/mmc/host/dw_mmc.c
parent0ddf03c95bbb4f4ed57281fa7b781472950df749 (diff)
mmc: dw_mmc: Handle late vmmc regulators with EPROBE_DEFER
It is possible to specify a regulator that should be turned on when dw_mmc is probed. At the moment dw_mmc will fail to use the regulator properly if the regulator probes after dw_mmc. Fix this problem by honoring EPROBE_DEFER. At the same time move the regulator code out of the slot init code. We only specify one regulator for the whole device and other parts of the code (like suspend/resume) assume that the regulator has only been enabled once. Signed-off-by: Doug Anderson <dianders@chromium.org> Signed-off-by: Chris Ball <cjb@laptop.org>
Diffstat (limited to 'drivers/mmc/host/dw_mmc.c')
-rw-r--r--drivers/mmc/host/dw_mmc.c34
1 files changed, 20 insertions, 14 deletions
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index 7dca5e92dcb4..957f5d7ea426 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -1991,19 +1991,6 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id)
1991#endif /* CONFIG_MMC_DW_IDMAC */ 1991#endif /* CONFIG_MMC_DW_IDMAC */
1992 } 1992 }
1993 1993
1994 host->vmmc = devm_regulator_get(mmc_dev(mmc), "vmmc");
1995 if (IS_ERR(host->vmmc)) {
1996 pr_info("%s: no vmmc regulator found\n", mmc_hostname(mmc));
1997 host->vmmc = NULL;
1998 } else {
1999 ret = regulator_enable(host->vmmc);
2000 if (ret) {
2001 dev_err(host->dev,
2002 "failed to enable regulator: %d\n", ret);
2003 goto err_setup_bus;
2004 }
2005 }
2006
2007 if (dw_mci_get_cd(mmc)) 1994 if (dw_mci_get_cd(mmc))
2008 set_bit(DW_MMC_CARD_PRESENT, &slot->flags); 1995 set_bit(DW_MMC_CARD_PRESENT, &slot->flags);
2009 else 1996 else
@@ -2235,11 +2222,29 @@ int dw_mci_probe(struct dw_mci *host)
2235 } 2222 }
2236 } 2223 }
2237 2224
2225 host->vmmc = devm_regulator_get(host->dev, "vmmc");
2226 if (IS_ERR(host->vmmc)) {
2227 ret = PTR_ERR(host->vmmc);
2228 if (ret == -EPROBE_DEFER)
2229 goto err_clk_ciu;
2230
2231 dev_info(host->dev, "no vmmc regulator found: %d\n", ret);
2232 host->vmmc = NULL;
2233 } else {
2234 ret = regulator_enable(host->vmmc);
2235 if (ret) {
2236 if (ret != -EPROBE_DEFER)
2237 dev_err(host->dev,
2238 "regulator_enable fail: %d\n", ret);
2239 goto err_clk_ciu;
2240 }
2241 }
2242
2238 if (!host->bus_hz) { 2243 if (!host->bus_hz) {
2239 dev_err(host->dev, 2244 dev_err(host->dev,
2240 "Platform data must supply bus speed\n"); 2245 "Platform data must supply bus speed\n");
2241 ret = -ENODEV; 2246 ret = -ENODEV;
2242 goto err_clk_ciu; 2247 goto err_regulator;
2243 } 2248 }
2244 2249
2245 host->quirks = host->pdata->quirks; 2250 host->quirks = host->pdata->quirks;
@@ -2386,6 +2391,7 @@ err_dmaunmap:
2386 if (host->use_dma && host->dma_ops->exit) 2391 if (host->use_dma && host->dma_ops->exit)
2387 host->dma_ops->exit(host); 2392 host->dma_ops->exit(host);
2388 2393
2394err_regulator:
2389 if (host->vmmc) 2395 if (host->vmmc)
2390 regulator_disable(host->vmmc); 2396 regulator_disable(host->vmmc);
2391 2397