diff options
author | Pierre Ossman <pierre@ossman.eu> | 2009-05-03 20:45:03 +0200 |
---|---|---|
committer | Pierre Ossman <pierre@ossman.eu> | 2009-06-13 22:42:57 +0200 |
commit | ae628903ab6cc9a04fdf8d4ff3f0c5b2ffa6f939 (patch) | |
tree | cf505d41100116d31692134fac3b2978cf8bda77 | |
parent | 7ceeb6a40a4dcc9b9cded6127ad5cdddb79b40ad (diff) |
sdhci: avoid changing voltage needlessly
Because of granularity issues, sometimes we told the hardware to change
to the voltage we were already at. Rework the logic so this doesn't
happen.
Signed-off-by: Pierre Ossman <pierre@ossman.eu>
-rw-r--r-- | drivers/mmc/host/sdhci.c | 53 | ||||
-rw-r--r-- | drivers/mmc/host/sdhci.h | 2 |
2 files changed, 29 insertions, 26 deletions
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 9234be2226e..1432a35690d 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -1005,12 +1005,34 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned short power) { u8 pwr; - if (host->power == power) + if (power == (unsigned short)-1) + pwr = 0; + else { + switch (1 << power) { + case MMC_VDD_165_195: + pwr = SDHCI_POWER_180; + break; + case MMC_VDD_29_30: + case MMC_VDD_30_31: + pwr = SDHCI_POWER_300; + break; + case MMC_VDD_32_33: + case MMC_VDD_33_34: + pwr = SDHCI_POWER_330; + break; + default: + BUG(); + } + } + + if (host->pwr == pwr) return; - if (power == (unsigned short)-1) { + host->pwr = pwr; + + if (pwr == 0) { sdhci_writeb(host, 0, SDHCI_POWER_CONTROL); - goto out; + return; } /* @@ -1020,35 +1042,16 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned short power) if (!(host->quirks & SDHCI_QUIRK_SINGLE_POWER_WRITE)) sdhci_writeb(host, 0, SDHCI_POWER_CONTROL); - pwr = SDHCI_POWER_ON; - - switch (1 << power) { - case MMC_VDD_165_195: - pwr |= SDHCI_POWER_180; - break; - case MMC_VDD_29_30: - case MMC_VDD_30_31: - pwr |= SDHCI_POWER_300; - break; - case MMC_VDD_32_33: - case MMC_VDD_33_34: - pwr |= SDHCI_POWER_330; - break; - default: - BUG(); - } - /* * At least the Marvell CaFe chip gets confused if we set the voltage * and set turn on power at the same time, so set the voltage first. */ if ((host->quirks & SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER)) - sdhci_writeb(host, pwr & ~SDHCI_POWER_ON, SDHCI_POWER_CONTROL); + sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL); - sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL); + pwr |= SDHCI_POWER_ON; -out: - host->power = power; + sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL); } /*****************************************************************************\ diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index 65c6f996bbd..2de08349c3c 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -255,7 +255,7 @@ struct sdhci_host { unsigned int timeout_clk; /* Timeout freq (KHz) */ unsigned int clock; /* Current clock (MHz) */ - unsigned short power; /* Current voltage */ + u8 pwr; /* Current voltage */ struct mmc_request *mrq; /* Current request */ struct mmc_command *cmd; /* Current command */ |