mmc: Add support for non-standard voltage switching
Pavan Kunapuli [Tue, 29 Nov 2011 14:26:40 +0000 (19:26 +0530)]
Adding quirk SDHCI_QUIRK_NON_STD_VOLTAGE_SWITCHING and
callback switch_signal_voltage in sdhci_ops to support
non standard signal voltage switching.

Bug 906650

Change-Id: If5538fb3177770ccb103305a7b3f0f7a6a8b92e6
Signed-off-by: Pavan Kunapuli <pkunapuli@nvidia.com>
Reviewed-on: http://git-master/r/67137
Reviewed-by: Sachin Nikam <snikam@nvidia.com>

drivers/mmc/host/sdhci.c
drivers/mmc/host/sdhci.h
include/linux/mmc/sdhci.h

index 760d54b..2471370 100644 (file)
@@ -1528,6 +1528,12 @@ static int sdhci_start_signal_voltage_switch(struct mmc_host *mmc,
        if (host->version < SDHCI_SPEC_300)
                return 0;
 
+       if (host->quirks & SDHCI_QUIRK_NON_STD_VOLTAGE_SWITCHING) {
+               if (host->ops->switch_signal_voltage)
+                       return host->ops->switch_signal_voltage(
+                               host, ios->signal_voltage);
+       }
+
        /*
         * We first check whether the request is to set signalling voltage
         * to 3.3V. If so, we change the voltage to 3.3V and return quickly.
@@ -1570,7 +1576,6 @@ static int sdhci_start_signal_voltage_switch(struct mmc_host *mmc,
 
                        /* Wait for 5ms */
                        usleep_range(5000, 5500);
-
                        ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
                        if (ctrl & SDHCI_CTRL_VDD_180) {
                                /* Provide SDCLK again and wait for 1ms*/
index 40619b7..1c12419 100644 (file)
@@ -273,9 +273,10 @@ struct sdhci_ops {
        void    (*platform_reset_enter)(struct sdhci_host *host, u8 mask);
        void    (*platform_reset_exit)(struct sdhci_host *host, u8 mask);
        int     (*set_uhs_signaling)(struct sdhci_host *host, unsigned int uhs);
-
-       int             (*suspend)(struct sdhci_host *host, pm_message_t state);
-       int             (*resume)(struct sdhci_host *host);
+       int     (*suspend)(struct sdhci_host *host, pm_message_t state);
+       int     (*resume)(struct sdhci_host *host);
+       int     (*switch_signal_voltage)(struct sdhci_host *host,
+                               unsigned int signal_voltage);
 };
 
 #ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS
index 9d499a0..0c7b586 100644 (file)
@@ -87,6 +87,8 @@ struct sdhci_host {
 #define SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC           (1<<30)
 /* The read-only detection via SDHCI_PRESENT_STATE register is unstable */
 #define SDHCI_QUIRK_UNSTABLE_RO_DETECT                 (1<<31)
+/* Controller cannot report the line status in present state register */
+#define SDHCI_QUIRK_NON_STD_VOLTAGE_SWITCHING          (1UL<<32)
 
        int irq;                /* Device IRQ */
        void __iomem *ioaddr;   /* Mapped address */