+/* Medfield eMMC hardware reset GPIOs */
+static int mfd_emmc0_rst_gpio = -EINVAL;
+static int mfd_emmc1_rst_gpio = -EINVAL;
+
+static int mfd_emmc_gpio_parse(struct sfi_table_header *table)
+{
+ struct sfi_table_simple *sb = (struct sfi_table_simple *)table;
+ struct sfi_gpio_table_entry *entry;
+ int i, num;
+
+ num = SFI_GET_NUM_ENTRIES(sb, struct sfi_gpio_table_entry);
+ entry = (struct sfi_gpio_table_entry *)sb->pentry;
+
+ for (i = 0; i < num; i++, entry++) {
+ if (!strncmp(entry->pin_name, "emmc0_rst", SFI_NAME_LEN))
+ mfd_emmc0_rst_gpio = entry->pin_no;
+ else if (!strncmp(entry->pin_name, "emmc1_rst", SFI_NAME_LEN))
+ mfd_emmc1_rst_gpio = entry->pin_no;
+ }
+
+ return 0;
+}
+
+#ifdef CONFIG_PM_RUNTIME
+
+static irqreturn_t mfd_sd_cd(int irq, void *dev_id)
+{
+ struct sdhci_pci_slot *slot = dev_id;
+ struct sdhci_host *host = slot->host;
+
+ mmc_detect_change(host->mmc, msecs_to_jiffies(200));
+ return IRQ_HANDLED;
+}
+
+#define MFLD_SD_CD_PIN 69
+
+static int mfd_sd_probe_slot(struct sdhci_pci_slot *slot)
+{
+ int err, irq, gpio = MFLD_SD_CD_PIN;
+
+ slot->cd_gpio = -EINVAL;
+ slot->cd_irq = -EINVAL;
+
+ err = gpio_request(gpio, "sd_cd");
+ if (err < 0)
+ goto out;
+
+ err = gpio_direction_input(gpio);
+ if (err < 0)
+ goto out_free;
+
+ irq = gpio_to_irq(gpio);
+ if (irq < 0)
+ goto out_free;
+
+ err = request_irq(irq, mfd_sd_cd, IRQF_TRIGGER_RISING |
+ IRQF_TRIGGER_FALLING, "sd_cd", slot);
+ if (err)
+ goto out_free;
+
+ slot->cd_gpio = gpio;
+ slot->cd_irq = irq;
+ slot->host->quirks2 |= SDHCI_QUIRK2_OWN_CARD_DETECTION;
+
+ return 0;
+
+out_free:
+ gpio_free(gpio);
+out:
+ dev_warn(&slot->chip->pdev->dev, "failed to setup card detect wake up\n");
+ return 0;
+}
+
+static void mfd_sd_remove_slot(struct sdhci_pci_slot *slot, int dead)
+{
+ if (slot->cd_irq >= 0)
+ free_irq(slot->cd_irq, slot);
+ gpio_free(slot->cd_gpio);
+}
+
+#else
+
+#define mfd_sd_probe_slot NULL
+#define mfd_sd_remove_slot NULL
+
+#endif
+