diff options
author | Yuvaraj CD <yuvaraj.cd@gmail.com> | 2014-08-22 09:47:50 -0400 |
---|---|---|
committer | Ulf Hansson <ulf.hansson@linaro.org> | 2014-09-09 07:59:18 -0400 |
commit | 51da2240906cb94e8f6ba55e403b6206df6fb2dd (patch) | |
tree | 8e8cc8e4a99b0fcd533dc2a9c6df1b0232bb8ced | |
parent | cc8aa7de48277f62fe3fced762d75f01ce57e909 (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.c | 72 | ||||
-rw-r--r-- | include/linux/mmc/dw_mmc.h | 2 |
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 | ||
2177 | err_setup_bus: | 2210 | err_setup_bus: |
2178 | mmc_free_host(mmc); | 2211 | mmc_free_host(mmc); |
2179 | return -EINVAL; | 2212 | return ret; |
2180 | } | 2213 | } |
2181 | 2214 | ||
2182 | static void dw_mci_cleanup_slot(struct dw_mci_slot *slot, unsigned int id) | 2215 | static 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: | |||
2630 | err_dmaunmap: | 2645 | err_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 | ||
2636 | err_clk_ciu: | 2649 | err_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 | */ |
2687 | int dw_mci_suspend(struct dw_mci *host) | 2697 | int 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 | } |
2694 | EXPORT_SYMBOL(dw_mci_suspend); | 2701 | EXPORT_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 | }; |