mmc: sdhci: Turn on controller clocks and card power at MMC_POWER_UP
Currently, the clock to the card is enabled prior to enabling the power to card. Specification requires that the power be supplied first and then a delay of 10ms and then clock be provided to the card. In this, during MMC_POWER_UP mode, the controller clocks would be ON and the power would be supplied to the card. In the MMC_POWER_ON mode, the clocks to the card would be enabled and the rate set. A callback has been provided to facilitate the enabling of controller clocks. CRs-Fixed: 567658 Change-Id: I2d66eae1581b9b136faaba4cafc330aeb6a3f364 Signed-off-by: Asutosh Das <asutoshd@codeaurora.org> [venkatg@codeaurora.org: Fix sdhci_set_power fn signature as it changed in 3.14 kernel] Signed-off-by: Venkat Gopalakrishnan <venkatg@codeaurora.org> [subhashj@codeaurora.org: fixed minor merge conflict] Signed-off-by: Subhash Jadavani <subhashj@codeaurora.org>
This commit is contained in:
parent
2c530476d3
commit
deba741527
2 changed files with 24 additions and 1 deletions
|
@ -1693,6 +1693,7 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
|
|||
unsigned long flags;
|
||||
u8 ctrl;
|
||||
struct mmc_host *mmc = host->mmc;
|
||||
int ret;
|
||||
|
||||
if (host->flags & SDHCI_DEVICE_DEAD) {
|
||||
if (!IS_ERR(mmc->supply.vmmc) &&
|
||||
|
@ -1706,6 +1707,25 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
|
|||
!(host->quirks2 & SDHCI_QUIRK2_PRESET_VALUE_BROKEN))
|
||||
sdhci_enable_preset_value(host, false);
|
||||
|
||||
/*
|
||||
* The controller clocks may be off during power-up and we may end up
|
||||
* enabling card clock before giving power to the card. Hence, during
|
||||
* MMC_POWER_UP enable the controller clock and turn-on the regulators.
|
||||
* The mmc_power_up would provide the necessary delay before turning on
|
||||
* the clocks to the card.
|
||||
*/
|
||||
if (ios->power_mode & MMC_POWER_UP) {
|
||||
if (host->ops->enable_controller_clock) {
|
||||
ret = host->ops->enable_controller_clock(host);
|
||||
if (ret) {
|
||||
pr_err("%s: enabling controller clock: failed: %d\n",
|
||||
mmc_hostname(host->mmc), ret);
|
||||
} else {
|
||||
sdhci_set_power(host, ios->power_mode, ios->vdd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&host->lock, flags);
|
||||
if (!ios->clock || ios->clock != host->clock) {
|
||||
spin_unlock_irqrestore(&host->lock, flags);
|
||||
|
@ -1727,7 +1747,9 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
|
|||
}
|
||||
spin_unlock_irqrestore(&host->lock, flags);
|
||||
|
||||
if (ios->power_mode & (MMC_POWER_UP | MMC_POWER_ON))
|
||||
if (!host->ops->enable_controller_clock && (ios->power_mode &
|
||||
(MMC_POWER_UP |
|
||||
MMC_POWER_ON)))
|
||||
sdhci_set_power(host, ios->power_mode, ios->vdd);
|
||||
|
||||
spin_lock_irqsave(&host->lock, flags);
|
||||
|
|
|
@ -640,6 +640,7 @@ struct sdhci_ops {
|
|||
int (*config_auto_tuning_cmd)(struct sdhci_host *host,
|
||||
bool enable,
|
||||
u32 type);
|
||||
int (*enable_controller_clock)(struct sdhci_host *host);
|
||||
void (*dump_vendor_regs)(struct sdhci_host *host);
|
||||
void (*toggle_cdr)(struct sdhci_host *host, bool enable);
|
||||
void (*voltage_switch)(struct sdhci_host *host);
|
||||
|
|
Loading…
Add table
Reference in a new issue