sdhci: avoid changing voltage needlessly
authorPierre Ossman <pierre@ossman.eu>
Sun, 3 May 2009 18:45:03 +0000 (20:45 +0200)
committerPierre Ossman <pierre@ossman.eu>
Sat, 13 Jun 2009 20:42:57 +0000 (22:42 +0200)
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>
drivers/mmc/host/sdhci.c
drivers/mmc/host/sdhci.h

index 9234be2226e743fc40b1d5b54e53a8500c09dd19..1432a35690dd59729f2626df5b1475381bd83750 100644 (file)
@@ -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);
 }
 
 /*****************************************************************************\
index 65c6f996bbd31cc7e9851ac781c69241c68c3fa5..2de08349c3ca95d0c9ac3fa387574a68b0a41834 100644 (file)
@@ -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 */