diff options
author | Ulf Hansson <ulf.hansson@linaro.org> | 2013-05-14 08:53:10 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2013-05-22 19:07:07 -0400 |
commit | 7c0136ef773c206e242b9718740377a45747bd70 (patch) | |
tree | 3daf9f446fbfd8f5b359a57987b629202548aaf4 /drivers/mmc | |
parent | 1fd83f0ecf87e33ab560e8229842cf10f91552ee (diff) |
ARM: 7721/1: mmc: mmci: Fixup regulator handling for vqmmc
We can not rely on regulator_is_enabled to decide whether to
enable|disable the regulator. It would mean that the reference
counter for it is not balanced properly.
Instead keep track of our internal state by using a new flag in
the host struct, so we can take correct decisions.
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'drivers/mmc')
-rw-r--r-- | drivers/mmc/host/mmci.c | 10 | ||||
-rw-r--r-- | drivers/mmc/host/mmci.h | 1 |
2 files changed, 7 insertions, 4 deletions
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index c6d8b6216069..a8bbdd1c4314 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c | |||
@@ -1156,9 +1156,10 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
1156 | if (!IS_ERR(mmc->supply.vmmc)) | 1156 | if (!IS_ERR(mmc->supply.vmmc)) |
1157 | mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, 0); | 1157 | mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, 0); |
1158 | 1158 | ||
1159 | if (!IS_ERR(mmc->supply.vqmmc) && | 1159 | if (!IS_ERR(mmc->supply.vqmmc) && host->vqmmc_enabled) { |
1160 | regulator_is_enabled(mmc->supply.vqmmc)) | ||
1161 | regulator_disable(mmc->supply.vqmmc); | 1160 | regulator_disable(mmc->supply.vqmmc); |
1161 | host->vqmmc_enabled = false; | ||
1162 | } | ||
1162 | 1163 | ||
1163 | break; | 1164 | break; |
1164 | case MMC_POWER_UP: | 1165 | case MMC_POWER_UP: |
@@ -1174,12 +1175,13 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
1174 | 1175 | ||
1175 | break; | 1176 | break; |
1176 | case MMC_POWER_ON: | 1177 | case MMC_POWER_ON: |
1177 | if (!IS_ERR(mmc->supply.vqmmc) && | 1178 | if (!IS_ERR(mmc->supply.vqmmc) && !host->vqmmc_enabled) { |
1178 | !regulator_is_enabled(mmc->supply.vqmmc)) { | ||
1179 | ret = regulator_enable(mmc->supply.vqmmc); | 1179 | ret = regulator_enable(mmc->supply.vqmmc); |
1180 | if (ret < 0) | 1180 | if (ret < 0) |
1181 | dev_err(mmc_dev(mmc), | 1181 | dev_err(mmc_dev(mmc), |
1182 | "failed to enable vqmmc regulator\n"); | 1182 | "failed to enable vqmmc regulator\n"); |
1183 | else | ||
1184 | host->vqmmc_enabled = true; | ||
1183 | } | 1185 | } |
1184 | 1186 | ||
1185 | pwr |= MCI_PWR_ON; | 1187 | pwr |= MCI_PWR_ON; |
diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h index 1f33ad5333a0..1383c9ce2646 100644 --- a/drivers/mmc/host/mmci.h +++ b/drivers/mmc/host/mmci.h | |||
@@ -183,6 +183,7 @@ struct mmci_host { | |||
183 | unsigned int cclk; | 183 | unsigned int cclk; |
184 | u32 pwr_reg; | 184 | u32 pwr_reg; |
185 | u32 clk_reg; | 185 | u32 clk_reg; |
186 | bool vqmmc_enabled; | ||
186 | struct mmci_platform_data *plat; | 187 | struct mmci_platform_data *plat; |
187 | struct variant_data *variant; | 188 | struct variant_data *variant; |
188 | 189 | ||