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);  | 
