]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - drivers/mmc/host/sdhci-acpi.c
mmc: sdhci: convert sdhci_set_clock() into a library function
[karo-tx-linux.git] / drivers / mmc / host / sdhci-acpi.c
index 9ce17f6e4014d9f4fc0b45c8e6856056ddebdb52..323e2a688563bc7b7bd50936207a795d0eab2e94 100644 (file)
@@ -31,7 +31,6 @@
 #include <linux/bitops.h>
 #include <linux/types.h>
 #include <linux/err.h>
-#include <linux/gpio/consumer.h>
 #include <linux/interrupt.h>
 #include <linux/acpi.h>
 #include <linux/pm.h>
 
 #include <linux/mmc/host.h>
 #include <linux/mmc/pm.h>
+#include <linux/mmc/slot-gpio.h>
 #include <linux/mmc/sdhci.h>
 
 #include "sdhci.h"
 
 enum {
-       SDHCI_ACPI_SD_CD        = BIT(0),
-       SDHCI_ACPI_RUNTIME_PM   = BIT(1),
+       SDHCI_ACPI_SD_CD                = BIT(0),
+       SDHCI_ACPI_RUNTIME_PM           = BIT(1),
+       SDHCI_ACPI_SD_CD_OVERRIDE_LEVEL = BIT(2),
 };
 
 struct sdhci_acpi_chip {
@@ -101,11 +102,17 @@ static void sdhci_acpi_int_hw_reset(struct sdhci_host *host)
 }
 
 static const struct sdhci_ops sdhci_acpi_ops_dflt = {
+       .set_clock = sdhci_set_clock,
        .enable_dma = sdhci_acpi_enable_dma,
+       .set_bus_width = sdhci_set_bus_width,
+       .reset = sdhci_reset,
 };
 
 static const struct sdhci_ops sdhci_acpi_ops_int = {
+       .set_clock = sdhci_set_clock,
        .enable_dma = sdhci_acpi_enable_dma,
+       .set_bus_width = sdhci_set_bus_width,
+       .reset = sdhci_reset,
        .hw_reset   = sdhci_acpi_int_hw_reset,
 };
 
@@ -121,6 +128,7 @@ static const struct sdhci_acpi_slot sdhci_acpi_slot_int_emmc = {
 };
 
 static const struct sdhci_acpi_slot sdhci_acpi_slot_int_sdio = {
+       .quirks  = SDHCI_QUIRK_BROKEN_CARD_DETECTION,
        .quirks2 = SDHCI_QUIRK2_HOST_OFF_CARD_ON,
        .caps    = MMC_CAP_NONREMOVABLE | MMC_CAP_POWER_OFF_CARD,
        .flags   = SDHCI_ACPI_RUNTIME_PM,
@@ -128,7 +136,8 @@ static const struct sdhci_acpi_slot sdhci_acpi_slot_int_sdio = {
 };
 
 static const struct sdhci_acpi_slot sdhci_acpi_slot_int_sd = {
-       .flags   = SDHCI_ACPI_SD_CD | SDHCI_ACPI_RUNTIME_PM,
+       .flags   = SDHCI_ACPI_SD_CD | SDHCI_ACPI_SD_CD_OVERRIDE_LEVEL |
+                  SDHCI_ACPI_RUNTIME_PM,
        .quirks2 = SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON,
 };
 
@@ -141,6 +150,7 @@ struct sdhci_acpi_uid_slot {
 static const struct sdhci_acpi_uid_slot sdhci_acpi_uids[] = {
        { "80860F14" , "1" , &sdhci_acpi_slot_int_emmc },
        { "80860F14" , "3" , &sdhci_acpi_slot_int_sd   },
+       { "80860F16" , NULL, &sdhci_acpi_slot_int_sd   },
        { "INT33BB"  , "2" , &sdhci_acpi_slot_int_sdio },
        { "INT33C6"  , NULL, &sdhci_acpi_slot_int_sdio },
        { "INT3436"  , NULL, &sdhci_acpi_slot_int_sdio },
@@ -150,6 +160,7 @@ static const struct sdhci_acpi_uid_slot sdhci_acpi_uids[] = {
 
 static const struct acpi_device_id sdhci_acpi_ids[] = {
        { "80860F14" },
+       { "80860F16" },
        { "INT33BB"  },
        { "INT33C6"  },
        { "INT3436"  },
@@ -192,59 +203,6 @@ static const struct sdhci_acpi_slot *sdhci_acpi_get_slot(acpi_handle handle,
        return slot;
 }
 
-#ifdef CONFIG_PM_RUNTIME
-
-static irqreturn_t sdhci_acpi_sd_cd(int irq, void *dev_id)
-{
-       mmc_detect_change(dev_id, msecs_to_jiffies(200));
-       return IRQ_HANDLED;
-}
-
-static int sdhci_acpi_add_own_cd(struct device *dev, struct mmc_host *mmc)
-{
-       struct gpio_desc *desc;
-       unsigned long flags;
-       int err, irq;
-
-       desc = devm_gpiod_get_index(dev, "sd_cd", 0);
-       if (IS_ERR(desc)) {
-               err = PTR_ERR(desc);
-               goto out;
-       }
-
-       err = gpiod_direction_input(desc);
-       if (err)
-               goto out_free;
-
-       irq = gpiod_to_irq(desc);
-       if (irq < 0) {
-               err = irq;
-               goto out_free;
-       }
-
-       flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING;
-       err = devm_request_irq(dev, irq, sdhci_acpi_sd_cd, flags, "sd_cd", mmc);
-       if (err)
-               goto out_free;
-
-       return 0;
-
-out_free:
-       devm_gpiod_put(dev, desc);
-out:
-       dev_warn(dev, "failed to setup card detect wake up\n");
-       return err;
-}
-
-#else
-
-static int sdhci_acpi_add_own_cd(struct device *dev, struct mmc_host *mmc)
-{
-       return 0;
-}
-
-#endif
-
 static int sdhci_acpi_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
@@ -332,15 +290,19 @@ static int sdhci_acpi_probe(struct platform_device *pdev)
 
        host->mmc->caps2 |= MMC_CAP2_NO_PRESCAN_POWERUP;
 
-       err = sdhci_add_host(host);
-       if (err)
-               goto err_free;
-
        if (sdhci_acpi_flag(c, SDHCI_ACPI_SD_CD)) {
-               if (sdhci_acpi_add_own_cd(dev, host->mmc))
+               bool v = sdhci_acpi_flag(c, SDHCI_ACPI_SD_CD_OVERRIDE_LEVEL);
+
+               if (mmc_gpiod_request_cd(host->mmc, NULL, 0, v, 0)) {
+                       dev_warn(dev, "failed to setup card detect gpio\n");
                        c->use_runtime_pm = false;
+               }
        }
 
+       err = sdhci_add_host(host);
+       if (err)
+               goto err_free;
+
        if (c->use_runtime_pm) {
                pm_runtime_set_active(dev);
                pm_suspend_ignore_children(dev, 1);