mmc: sdhci-esdhc-imx: support of 1.8V is board specific

Signed-off-by: Eric Miao <eric.miao@linaro.org>
diff --git a/arch/arm/plat-mxc/include/mach/esdhc.h b/arch/arm/plat-mxc/include/mach/esdhc.h
index aaf9748..4ab603e 100644
--- a/arch/arm/plat-mxc/include/mach/esdhc.h
+++ b/arch/arm/plat-mxc/include/mach/esdhc.h
@@ -32,6 +32,7 @@
  * @cd_gpio:	gpio for card_detect interrupt
  * @wp_type:	type of write_protect method (see wp_types enum above)
  * @cd_type:	type of card_detect method (see cd_types enum above)
+ * @vdd_180:	1.8V VDD supported
  */
 
 struct esdhc_platform_data {
@@ -39,5 +40,6 @@
 	unsigned int cd_gpio;
 	enum wp_types wp_type;
 	enum cd_types cd_type;
+	int vdd_180;
 };
 #endif /* __ASM_ARCH_IMX_ESDHC_H */
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index f2a05ea..d426b0e 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -740,11 +740,10 @@
 		ocr |= SD_OCR_CCS;
 
 	/*
-	 * If the host supports one of UHS-I modes, request the card
-	 * to switch to 1.8V signaling level.
+	 * If the host supports one of UHS-I modes, and support 1.8V VDD,
+	 * request the card to switch to 1.8V signaling level.
 	 */
-	if (host->caps & (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 |
-	    MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104 | MMC_CAP_UHS_DDR50))
+	if ((host->caps & (MMC_CAP_UHS)) && (host->ocr_avail_sd & MMC_VDD_165_195))
 		ocr |= SD_OCR_S18R;
 
 	/* If the host can supply more than 150mA, XPC should be set to 1. */
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index 7f6d625..4a2a9f6 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -1,4 +1,5 @@
 /*
+#define MMC_CAP_UHS		(
  * Freescale eSDHC i.MX controller driver for the platform bus.
  *
  * derived from the OF-version.
@@ -77,6 +78,7 @@
 struct pltfm_imx_data {
 	int flags;
 	u32 scratchpad;
+	int can_vdd_180;	/* support 1.8V? */
 	enum imx_esdhc_type devtype;
 	struct esdhc_platform_data boarddata;
 };
@@ -462,6 +464,8 @@
 	if (gpio_is_valid(boarddata->wp_gpio))
 		boarddata->wp_type = ESDHC_WP_GPIO;
 
+	if (of_get_property(np, "support-vdd-180", NULL))
+		boarddata->vdd_180 = 1;
 	return 0;
 }
 #else
@@ -566,6 +570,16 @@
 		boarddata->wp_gpio = -EINVAL;
 	}
 
+	/* The imx6q uSDHC capabilities will always claim to support 1.8V
+	 * while this is board specific,  should be initialized properly
+	 */
+	if (is_imx6q_usdhc(imx_data)) {
+		host->quirks |= SDHCI_QUIRK_MISSING_CAPS;
+		host->caps = readl(host->ioaddr + SDHCI_CAPABILITIES);
+		if (!boarddata->vdd_180)
+			host->caps &= ~SDHCI_CAN_VDD_180;
+	}
+
 	/* card_detect */
 	if (boarddata->cd_type != ESDHC_CD_GPIO)
 		boarddata->cd_gpio = -EINVAL;
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index a3ac9c4..56b13b2 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -236,6 +236,12 @@
 #define MMC_CAP_CMD23		(1 << 30)	/* CMD23 supported. */
 #define MMC_CAP_HW_RESET	(1 << 31)	/* Hardware reset */
 
+#define MMC_CAP_UHS		(MMC_CAP_UHS_SDR12 |\
+				 MMC_CAP_UHS_SDR25 |\
+				 MMC_CAP_UHS_SDR50 |\
+				 MMC_CAP_UHS_SDR104 |\
+				 MMC_CAP_UHS_DDR50)
+
 	unsigned int		caps2;		/* More host capabilities */
 
 #define MMC_CAP2_BOOTPART_NOACC	(1 << 0)	/* Boot partition no access */