aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYuvaraj CD <yuvaraj.cd@gmail.com>2014-08-22 09:47:50 -0400
committerUlf Hansson <ulf.hansson@linaro.org>2014-09-09 07:59:18 -0400
commit51da2240906cb94e8f6ba55e403b6206df6fb2dd (patch)
tree8e8cc8e4a99b0fcd533dc2a9c6df1b0232bb8ced
parentcc8aa7de48277f62fe3fced762d75f01ce57e909 (diff)
mmc: dw_mmc: use mmc_regulator_get_supply to handle regulators
This patch makes use of mmc_regulator_get_supply() to handle the vmmc and vqmmc regulators.Also it moves the code handling the these regulators to dw_mci_set_ios().It turned on the vmmc and vqmmc during MMC_POWER_UP and MMC_POWER_ON,and turned off during MMC_POWER_OFF. Signed-off-by: Yuvaraj Kumar C D <yuvaraj.cd@samsung.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
-rw-r--r--drivers/mmc/host/dw_mmc.c72
-rw-r--r--include/linux/mmc/dw_mmc.h2
2 files changed, 36 insertions, 38 deletions
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index 7f227e964265..aadb0d6aa63f 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -936,6 +936,7 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
936 struct dw_mci_slot *slot = mmc_priv(mmc); 936 struct dw_mci_slot *slot = mmc_priv(mmc);
937 const struct dw_mci_drv_data *drv_data = slot->host->drv_data; 937 const struct dw_mci_drv_data *drv_data = slot->host->drv_data;
938 u32 regs; 938 u32 regs;
939 int ret;
939 940
940 switch (ios->bus_width) { 941 switch (ios->bus_width) {
941 case MMC_BUS_WIDTH_4: 942 case MMC_BUS_WIDTH_4:
@@ -974,12 +975,38 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
974 975
975 switch (ios->power_mode) { 976 switch (ios->power_mode) {
976 case MMC_POWER_UP: 977 case MMC_POWER_UP:
978 if (!IS_ERR(mmc->supply.vmmc)) {
979 ret = mmc_regulator_set_ocr(mmc, mmc->supply.vmmc,
980 ios->vdd);
981 if (ret) {
982 dev_err(slot->host->dev,
983 "failed to enable vmmc regulator\n");
984 /*return, if failed turn on vmmc*/
985 return;
986 }
987 }
988 if (!IS_ERR(mmc->supply.vqmmc) && !slot->host->vqmmc_enabled) {
989 ret = regulator_enable(mmc->supply.vqmmc);
990 if (ret < 0)
991 dev_err(slot->host->dev,
992 "failed to enable vqmmc regulator\n");
993 else
994 slot->host->vqmmc_enabled = true;
995 }
977 set_bit(DW_MMC_CARD_NEED_INIT, &slot->flags); 996 set_bit(DW_MMC_CARD_NEED_INIT, &slot->flags);
978 regs = mci_readl(slot->host, PWREN); 997 regs = mci_readl(slot->host, PWREN);
979 regs |= (1 << slot->id); 998 regs |= (1 << slot->id);
980 mci_writel(slot->host, PWREN, regs); 999 mci_writel(slot->host, PWREN, regs);
981 break; 1000 break;
982 case MMC_POWER_OFF: 1001 case MMC_POWER_OFF:
1002 if (!IS_ERR(mmc->supply.vmmc))
1003 mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, 0);
1004
1005 if (!IS_ERR(mmc->supply.vqmmc) && slot->host->vqmmc_enabled) {
1006 regulator_disable(mmc->supply.vqmmc);
1007 slot->host->vqmmc_enabled = false;
1008 }
1009
983 regs = mci_readl(slot->host, PWREN); 1010 regs = mci_readl(slot->host, PWREN);
984 regs &= ~(1 << slot->id); 1011 regs &= ~(1 << slot->id);
985 mci_writel(slot->host, PWREN, regs); 1012 mci_writel(slot->host, PWREN, regs);
@@ -2110,7 +2137,13 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id)
2110 mmc->f_max = freq[1]; 2137 mmc->f_max = freq[1];
2111 } 2138 }
2112 2139
2113 mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; 2140 /*if there are external regulators, get them*/
2141 ret = mmc_regulator_get_supply(mmc);
2142 if (ret == -EPROBE_DEFER)
2143 goto err_setup_bus;
2144
2145 if (!mmc->ocr_avail)
2146 mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
2114 2147
2115 if (host->pdata->caps) 2148 if (host->pdata->caps)
2116 mmc->caps = host->pdata->caps; 2149 mmc->caps = host->pdata->caps;
@@ -2176,7 +2209,7 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id)
2176 2209
2177err_setup_bus: 2210err_setup_bus:
2178 mmc_free_host(mmc); 2211 mmc_free_host(mmc);
2179 return -EINVAL; 2212 return ret;
2180} 2213}
2181 2214
2182static void dw_mci_cleanup_slot(struct dw_mci_slot *slot, unsigned int id) 2215static void dw_mci_cleanup_slot(struct dw_mci_slot *slot, unsigned int id)
@@ -2469,24 +2502,6 @@ int dw_mci_probe(struct dw_mci *host)
2469 } 2502 }
2470 } 2503 }
2471 2504
2472 host->vmmc = devm_regulator_get_optional(host->dev, "vmmc");
2473 if (IS_ERR(host->vmmc)) {
2474 ret = PTR_ERR(host->vmmc);
2475 if (ret == -EPROBE_DEFER)
2476 goto err_clk_ciu;
2477
2478 dev_info(host->dev, "no vmmc regulator found: %d\n", ret);
2479 host->vmmc = NULL;
2480 } else {
2481 ret = regulator_enable(host->vmmc);
2482 if (ret) {
2483 if (ret != -EPROBE_DEFER)
2484 dev_err(host->dev,
2485 "regulator_enable fail: %d\n", ret);
2486 goto err_clk_ciu;
2487 }
2488 }
2489
2490 host->quirks = host->pdata->quirks; 2505 host->quirks = host->pdata->quirks;
2491 2506
2492 spin_lock_init(&host->lock); 2507 spin_lock_init(&host->lock);
@@ -2630,8 +2645,6 @@ err_workqueue:
2630err_dmaunmap: 2645err_dmaunmap:
2631 if (host->use_dma && host->dma_ops->exit) 2646 if (host->use_dma && host->dma_ops->exit)
2632 host->dma_ops->exit(host); 2647 host->dma_ops->exit(host);
2633 if (host->vmmc)
2634 regulator_disable(host->vmmc);
2635 2648
2636err_clk_ciu: 2649err_clk_ciu:
2637 if (!IS_ERR(host->ciu_clk)) 2650 if (!IS_ERR(host->ciu_clk))
@@ -2667,9 +2680,6 @@ void dw_mci_remove(struct dw_mci *host)
2667 if (host->use_dma && host->dma_ops->exit) 2680 if (host->use_dma && host->dma_ops->exit)
2668 host->dma_ops->exit(host); 2681 host->dma_ops->exit(host);
2669 2682
2670 if (host->vmmc)
2671 regulator_disable(host->vmmc);
2672
2673 if (!IS_ERR(host->ciu_clk)) 2683 if (!IS_ERR(host->ciu_clk))
2674 clk_disable_unprepare(host->ciu_clk); 2684 clk_disable_unprepare(host->ciu_clk);
2675 2685
@@ -2686,9 +2696,6 @@ EXPORT_SYMBOL(dw_mci_remove);
2686 */ 2696 */
2687int dw_mci_suspend(struct dw_mci *host) 2697int dw_mci_suspend(struct dw_mci *host)
2688{ 2698{
2689 if (host->vmmc)
2690 regulator_disable(host->vmmc);
2691
2692 return 0; 2699 return 0;
2693} 2700}
2694EXPORT_SYMBOL(dw_mci_suspend); 2701EXPORT_SYMBOL(dw_mci_suspend);
@@ -2697,15 +2704,6 @@ int dw_mci_resume(struct dw_mci *host)
2697{ 2704{
2698 int i, ret; 2705 int i, ret;
2699 2706
2700 if (host->vmmc) {
2701 ret = regulator_enable(host->vmmc);
2702 if (ret) {
2703 dev_err(host->dev,
2704 "failed to enable regulator: %d\n", ret);
2705 return ret;
2706 }
2707 }
2708
2709 if (!dw_mci_ctrl_reset(host, SDMMC_CTRL_ALL_RESET_FLAGS)) { 2707 if (!dw_mci_ctrl_reset(host, SDMMC_CTRL_ALL_RESET_FLAGS)) {
2710 ret = -ENODEV; 2708 ret = -ENODEV;
2711 return ret; 2709 return ret;
diff --git a/include/linux/mmc/dw_mmc.h b/include/linux/mmc/dw_mmc.h
index 29ce014ab421..84e2827d0f0b 100644
--- a/include/linux/mmc/dw_mmc.h
+++ b/include/linux/mmc/dw_mmc.h
@@ -188,7 +188,7 @@ struct dw_mci {
188 /* Workaround flags */ 188 /* Workaround flags */
189 u32 quirks; 189 u32 quirks;
190 190
191 struct regulator *vmmc; /* Power regulator */ 191 bool vqmmc_enabled;
192 unsigned long irq_flags; /* IRQ flags */ 192 unsigned long irq_flags; /* IRQ flags */
193 int irq; 193 int irq;
194}; 194};