diff options
Diffstat (limited to 'drivers/mmc/host/sdhci-acpi.c')
| -rw-r--r-- | drivers/mmc/host/sdhci-acpi.c | 100 |
1 files changed, 32 insertions, 68 deletions
diff --git a/drivers/mmc/host/sdhci-acpi.c b/drivers/mmc/host/sdhci-acpi.c index cdd4ce0d7c9..8ce3c28cb76 100644 --- a/drivers/mmc/host/sdhci-acpi.c +++ b/drivers/mmc/host/sdhci-acpi.c @@ -31,23 +31,23 @@ #include <linux/bitops.h> #include <linux/types.h> #include <linux/err.h> -#include <linux/gpio.h> #include <linux/interrupt.h> #include <linux/acpi.h> -#include <linux/acpi_gpio.h> #include <linux/pm.h> #include <linux/pm_runtime.h> #include <linux/delay.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 { @@ -102,11 +102,19 @@ 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, + .set_uhs_signaling = sdhci_set_uhs_signaling, }; 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, + .set_uhs_signaling = sdhci_set_uhs_signaling, .hw_reset = sdhci_acpi_int_hw_reset, }; @@ -122,6 +130,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, @@ -129,7 +138,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, }; @@ -142,16 +152,20 @@ 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 }, { "PNP0D40" }, { }, }; static const struct acpi_device_id sdhci_acpi_ids[] = { { "80860F14" }, + { "80860F16" }, { "INT33BB" }, { "INT33C6" }, + { "INT3436" }, { "PNP0D40" }, { }, }; @@ -191,59 +205,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, int gpio, - struct mmc_host *mmc) -{ - unsigned long flags; - int err, irq; - - if (gpio < 0) { - err = gpio; - goto out; - } - - err = devm_gpio_request_one(dev, gpio, GPIOF_DIR_IN, "sd_cd"); - if (err) - goto out; - - irq = gpio_to_irq(gpio); - 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_gpio_free(dev, gpio); -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, int gpio, - struct mmc_host *mmc) -{ - return 0; -} - -#endif - static int sdhci_acpi_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -254,7 +215,7 @@ static int sdhci_acpi_probe(struct platform_device *pdev) struct resource *iomem; resource_size_t len; const char *hid; - int err, gpio; + int err; if (acpi_bus_get_device(handle, &device)) return -ENODEV; @@ -279,8 +240,6 @@ static int sdhci_acpi_probe(struct platform_device *pdev) if (IS_ERR(host)) return PTR_ERR(host); - gpio = acpi_get_gpio_by_index(dev, 0, NULL); - c = sdhci_priv(host); c->host = host; c->slot = sdhci_acpi_get_slot(handle, hid); @@ -310,8 +269,9 @@ static int sdhci_acpi_probe(struct platform_device *pdev) dma_mask = DMA_BIT_MASK(32); } - dev->dma_mask = &dev->coherent_dma_mask; - dev->coherent_dma_mask = dma_mask; + err = dma_coerce_mask_and_coherent(dev, dma_mask); + if (err) + goto err_free; } if (c->slot) { @@ -332,15 +292,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, gpio, 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); |
