static int jmicron_probe(struct sdhci_pci_chip *chip)
 {
        int ret;
+       u16 mmcdev = 0;
 
        if (chip->pdev->revision == 0) {
                chip->quirks |= SDHCI_QUIRK_32BIT_DMA_ADDR |
         * 2. The MMC interface has a lower subfunction number
         *    than the SD interface.
         */
-       if (chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB38X_SD) {
+       if (chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB38X_SD)
+               mmcdev = PCI_DEVICE_ID_JMICRON_JMB38X_MMC;
+       else if (chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB388_SD)
+               mmcdev = PCI_DEVICE_ID_JMICRON_JMB388_ESD;
+
+       if (mmcdev) {
                struct pci_dev *sd_dev;
 
                sd_dev = NULL;
                while ((sd_dev = pci_get_device(PCI_VENDOR_ID_JMICRON,
-                       PCI_DEVICE_ID_JMICRON_JMB38X_MMC, sd_dev)) != NULL) {
+                                               mmcdev, sd_dev)) != NULL) {
                        if ((PCI_SLOT(chip->pdev->devfn) ==
                                PCI_SLOT(sd_dev->devfn)) &&
                                (chip->pdev->bus == sd_dev->bus))
                        slot->host->quirks |= SDHCI_QUIRK_BROKEN_ADMA;
        }
 
+       /* JM388 MMC doesn't support 1.8V while SD supports it */
+       if (slot->chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB388_ESD) {
+               slot->host->ocr_avail_sd = MMC_VDD_32_33 | MMC_VDD_33_34 |
+                       MMC_VDD_29_30 | MMC_VDD_30_31 |
+                       MMC_VDD_165_195; /* allow 1.8V */
+               slot->host->ocr_avail_mmc = MMC_VDD_32_33 | MMC_VDD_33_34 |
+                       MMC_VDD_29_30 | MMC_VDD_30_31; /* no 1.8V for MMC */
+       }
+
        /*
         * The secondary interface requires a bit set to get the
         * interrupts.
         */
-       if (slot->chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB38X_MMC)
+       if (slot->chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB38X_MMC ||
+           slot->chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB388_ESD)
                jmicron_enable_mmc(slot->host, 1);
 
        return 0;
        if (dead)
                return;
 
-       if (slot->chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB38X_MMC)
+       if (slot->chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB38X_MMC ||
+           slot->chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB388_ESD)
                jmicron_enable_mmc(slot->host, 0);
 }
 
 {
        int i;
 
-       if (chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB38X_MMC) {
+       if (chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB38X_MMC ||
+           chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB388_ESD) {
                for (i = 0;i < chip->num_slots;i++)
                        jmicron_enable_mmc(chip->slots[i]->host, 0);
        }
 {
        int ret, i;
 
-       if (chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB38X_MMC) {
+       if (chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB38X_MMC ||
+           chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB388_ESD) {
                for (i = 0;i < chip->num_slots;i++)
                        jmicron_enable_mmc(chip->slots[i]->host, 1);
        }
                .driver_data    = (kernel_ulong_t)&sdhci_jmicron,
        },
 
+       {
+               .vendor         = PCI_VENDOR_ID_JMICRON,
+               .device         = PCI_DEVICE_ID_JMICRON_JMB388_SD,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .driver_data    = (kernel_ulong_t)&sdhci_jmicron,
+       },
+
+       {
+               .vendor         = PCI_VENDOR_ID_JMICRON,
+               .device         = PCI_DEVICE_ID_JMICRON_JMB388_ESD,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .driver_data    = (kernel_ulong_t)&sdhci_jmicron,
+       },
+
        {
                .vendor         = PCI_VENDOR_ID_SYSKONNECT,
                .device         = 0x8000,
 
 int sdhci_add_host(struct sdhci_host *host)
 {
        struct mmc_host *mmc;
-       unsigned int caps;
+       unsigned int caps, ocr_avail;
        int ret;
 
        WARN_ON(host == NULL);
            mmc_card_is_removable(mmc))
                mmc->caps |= MMC_CAP_NEEDS_POLL;
 
-       mmc->ocr_avail = 0;
+       ocr_avail = 0;
        if (caps & SDHCI_CAN_VDD_330)
-               mmc->ocr_avail |= MMC_VDD_32_33|MMC_VDD_33_34;
+               ocr_avail |= MMC_VDD_32_33 | MMC_VDD_33_34;
        if (caps & SDHCI_CAN_VDD_300)
-               mmc->ocr_avail |= MMC_VDD_29_30|MMC_VDD_30_31;
+               ocr_avail |= MMC_VDD_29_30 | MMC_VDD_30_31;
        if (caps & SDHCI_CAN_VDD_180)
-               mmc->ocr_avail |= MMC_VDD_165_195;
+               ocr_avail |= MMC_VDD_165_195;
+
+       mmc->ocr_avail = ocr_avail;
+       mmc->ocr_avail_sdio = ocr_avail;
+       if (host->ocr_avail_sdio)
+               mmc->ocr_avail_sdio &= host->ocr_avail_sdio;
+       mmc->ocr_avail_sd = ocr_avail;
+       if (host->ocr_avail_sd)
+               mmc->ocr_avail_sd &= host->ocr_avail_sd;
+       else /* normal SD controllers don't support 1.8V */
+               mmc->ocr_avail_sd &= ~MMC_VDD_165_195;
+       mmc->ocr_avail_mmc = ocr_avail;
+       if (host->ocr_avail_mmc)
+               mmc->ocr_avail_mmc &= host->ocr_avail_mmc;
 
        if (mmc->ocr_avail == 0) {
                printk(KERN_ERR "%s: Hardware doesn't report any "