diff options
author | Pierre Ossman <pierre@ossman.eu> | 2009-05-03 14:45:03 -0400 |
---|---|---|
committer | Pierre Ossman <pierre@ossman.eu> | 2009-06-13 16:42:57 -0400 |
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 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 | ||
1050 | out: | 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 */ |