aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorPierre Ossman <pierre@ossman.eu>2009-05-03 14:45:03 -0400
committerPierre Ossman <pierre@ossman.eu>2009-06-13 16:42:57 -0400
commitae628903ab6cc9a04fdf8d4ff3f0c5b2ffa6f939 (patch)
treecf505d41100116d31692134fac3b2978cf8bda77 /drivers
parent7ceeb6a40a4dcc9b9cded6127ad5cdddb79b40ad (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>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mmc/host/sdhci.c53
-rw-r--r--drivers/mmc/host/sdhci.h2
2 files changed, 29 insertions, 26 deletions
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 9234be2226e7..1432a35690dd 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)
1005{ 1005{
1006 u8 pwr; 1006 u8 pwr;
1007 1007
1008 if (host->power == power) 1008 if (power == (unsigned short)-1)
1009 pwr = 0;
1010 else {
1011 switch (1 << power) {
1012 case MMC_VDD_165_195:
1013 pwr = SDHCI_POWER_180;
1014 break;
1015 case MMC_VDD_29_30:
1016 case MMC_VDD_30_31:
1017 pwr = SDHCI_POWER_300;
1018 break;
1019 case MMC_VDD_32_33:
1020 case MMC_VDD_33_34:
1021 pwr = SDHCI_POWER_330;
1022 break;
1023 default:
1024 BUG();
1025 }
1026 }
1027
1028 if (host->pwr == pwr)
1009 return; 1029 return;
1010 1030
1011 if (power == (unsigned short)-1) { 1031 host->pwr = pwr;
1032
1033 if (pwr == 0) {
1012 sdhci_writeb(host, 0, SDHCI_POWER_CONTROL); 1034 sdhci_writeb(host, 0, SDHCI_POWER_CONTROL);
1013 goto out; 1035 return;
1014 } 1036 }
1015 1037
1016 /* 1038 /*
@@ -1020,35 +1042,16 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned short power)
1020 if (!(host->quirks & SDHCI_QUIRK_SINGLE_POWER_WRITE)) 1042 if (!(host->quirks & SDHCI_QUIRK_SINGLE_POWER_WRITE))
1021 sdhci_writeb(host, 0, SDHCI_POWER_CONTROL); 1043 sdhci_writeb(host, 0, SDHCI_POWER_CONTROL);
1022 1044
1023 pwr = SDHCI_POWER_ON;
1024
1025 switch (1 << power) {
1026 case MMC_VDD_165_195:
1027 pwr |= SDHCI_POWER_180;
1028 break;
1029 case MMC_VDD_29_30:
1030 case MMC_VDD_30_31:
1031 pwr |= SDHCI_POWER_300;
1032 break;
1033 case MMC_VDD_32_33:
1034 case MMC_VDD_33_34:
1035 pwr |= SDHCI_POWER_330;
1036 break;
1037 default:
1038 BUG();
1039 }
1040
1041 /* 1045 /*
1042 * At least the Marvell CaFe chip gets confused if we set the voltage 1046 * At least the Marvell CaFe chip gets confused if we set the voltage
1043 * and set turn on power at the same time, so set the voltage first. 1047 * and set turn on power at the same time, so set the voltage first.
1044 */ 1048 */
1045 if ((host->quirks & SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER)) 1049 if ((host->quirks & SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER))
1046 sdhci_writeb(host, pwr & ~SDHCI_POWER_ON, SDHCI_POWER_CONTROL); 1050 sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
1047 1051
1048 sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL); 1052 pwr |= SDHCI_POWER_ON;
1049 1053
1050out: 1054 sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
1051 host->power = power;
1052} 1055}
1053 1056
1054/*****************************************************************************\ 1057/*****************************************************************************\
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index 65c6f996bbd3..2de08349c3ca 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -255,7 +255,7 @@ struct sdhci_host {
255 unsigned int timeout_clk; /* Timeout freq (KHz) */ 255 unsigned int timeout_clk; /* Timeout freq (KHz) */
256 256
257 unsigned int clock; /* Current clock (MHz) */ 257 unsigned int clock; /* Current clock (MHz) */
258 unsigned short power; /* Current voltage */ 258 u8 pwr; /* Current voltage */
259 259
260 struct mmc_request *mrq; /* Current request */ 260 struct mmc_request *mrq; /* Current request */
261 struct mmc_command *cmd; /* Current command */ 261 struct mmc_command *cmd; /* Current command */