diff options
Diffstat (limited to 'drivers/mmc/host/sdhci-acpi.c')
-rw-r--r-- | drivers/mmc/host/sdhci-acpi.c | 80 |
1 files changed, 18 insertions, 62 deletions
diff --git a/drivers/mmc/host/sdhci-acpi.c b/drivers/mmc/host/sdhci-acpi.c index 9ce17f6e4014..ebb3f392b589 100644 --- a/drivers/mmc/host/sdhci-acpi.c +++ b/drivers/mmc/host/sdhci-acpi.c @@ -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> @@ -40,13 +39,15 @@ #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 { @@ -121,6 +122,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 +130,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 +144,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 +154,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 +197,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 +284,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); |