diff options
| -rw-r--r-- | drivers/mmc/host/sdhci-acpi.c | 77 |
1 files changed, 15 insertions, 62 deletions
diff --git a/drivers/mmc/host/sdhci-acpi.c b/drivers/mmc/host/sdhci-acpi.c index 9ce17f6e4014..98c7420c5f75 100644 --- a/drivers/mmc/host/sdhci-acpi.c +++ b/drivers/mmc/host/sdhci-acpi.c | |||
| @@ -31,7 +31,6 @@ | |||
| 31 | #include <linux/bitops.h> | 31 | #include <linux/bitops.h> |
| 32 | #include <linux/types.h> | 32 | #include <linux/types.h> |
| 33 | #include <linux/err.h> | 33 | #include <linux/err.h> |
| 34 | #include <linux/gpio/consumer.h> | ||
| 35 | #include <linux/interrupt.h> | 34 | #include <linux/interrupt.h> |
| 36 | #include <linux/acpi.h> | 35 | #include <linux/acpi.h> |
| 37 | #include <linux/pm.h> | 36 | #include <linux/pm.h> |
| @@ -40,13 +39,15 @@ | |||
| 40 | 39 | ||
| 41 | #include <linux/mmc/host.h> | 40 | #include <linux/mmc/host.h> |
| 42 | #include <linux/mmc/pm.h> | 41 | #include <linux/mmc/pm.h> |
| 42 | #include <linux/mmc/slot-gpio.h> | ||
| 43 | #include <linux/mmc/sdhci.h> | 43 | #include <linux/mmc/sdhci.h> |
| 44 | 44 | ||
| 45 | #include "sdhci.h" | 45 | #include "sdhci.h" |
| 46 | 46 | ||
| 47 | enum { | 47 | enum { |
| 48 | SDHCI_ACPI_SD_CD = BIT(0), | 48 | SDHCI_ACPI_SD_CD = BIT(0), |
| 49 | SDHCI_ACPI_RUNTIME_PM = BIT(1), | 49 | SDHCI_ACPI_RUNTIME_PM = BIT(1), |
| 50 | SDHCI_ACPI_SD_CD_OVERRIDE_LEVEL = BIT(2), | ||
| 50 | }; | 51 | }; |
| 51 | 52 | ||
| 52 | struct sdhci_acpi_chip { | 53 | struct sdhci_acpi_chip { |
| @@ -128,7 +129,8 @@ static const struct sdhci_acpi_slot sdhci_acpi_slot_int_sdio = { | |||
| 128 | }; | 129 | }; |
| 129 | 130 | ||
| 130 | static const struct sdhci_acpi_slot sdhci_acpi_slot_int_sd = { | 131 | static const struct sdhci_acpi_slot sdhci_acpi_slot_int_sd = { |
| 131 | .flags = SDHCI_ACPI_SD_CD | SDHCI_ACPI_RUNTIME_PM, | 132 | .flags = SDHCI_ACPI_SD_CD | SDHCI_ACPI_SD_CD_OVERRIDE_LEVEL | |
| 133 | SDHCI_ACPI_RUNTIME_PM, | ||
| 132 | .quirks2 = SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON, | 134 | .quirks2 = SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON, |
| 133 | }; | 135 | }; |
| 134 | 136 | ||
| @@ -192,59 +194,6 @@ static const struct sdhci_acpi_slot *sdhci_acpi_get_slot(acpi_handle handle, | |||
| 192 | return slot; | 194 | return slot; |
| 193 | } | 195 | } |
| 194 | 196 | ||
| 195 | #ifdef CONFIG_PM_RUNTIME | ||
| 196 | |||
| 197 | static irqreturn_t sdhci_acpi_sd_cd(int irq, void *dev_id) | ||
| 198 | { | ||
| 199 | mmc_detect_change(dev_id, msecs_to_jiffies(200)); | ||
| 200 | return IRQ_HANDLED; | ||
| 201 | } | ||
| 202 | |||
| 203 | static int sdhci_acpi_add_own_cd(struct device *dev, struct mmc_host *mmc) | ||
| 204 | { | ||
| 205 | struct gpio_desc *desc; | ||
| 206 | unsigned long flags; | ||
| 207 | int err, irq; | ||
| 208 | |||
| 209 | desc = devm_gpiod_get_index(dev, "sd_cd", 0); | ||
| 210 | if (IS_ERR(desc)) { | ||
| 211 | err = PTR_ERR(desc); | ||
| 212 | goto out; | ||
| 213 | } | ||
| 214 | |||
| 215 | err = gpiod_direction_input(desc); | ||
| 216 | if (err) | ||
| 217 | goto out_free; | ||
| 218 | |||
| 219 | irq = gpiod_to_irq(desc); | ||
| 220 | if (irq < 0) { | ||
| 221 | err = irq; | ||
| 222 | goto out_free; | ||
| 223 | } | ||
| 224 | |||
| 225 | flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING; | ||
| 226 | err = devm_request_irq(dev, irq, sdhci_acpi_sd_cd, flags, "sd_cd", mmc); | ||
| 227 | if (err) | ||
| 228 | goto out_free; | ||
| 229 | |||
| 230 | return 0; | ||
| 231 | |||
| 232 | out_free: | ||
| 233 | devm_gpiod_put(dev, desc); | ||
| 234 | out: | ||
| 235 | dev_warn(dev, "failed to setup card detect wake up\n"); | ||
| 236 | return err; | ||
| 237 | } | ||
| 238 | |||
| 239 | #else | ||
| 240 | |||
| 241 | static int sdhci_acpi_add_own_cd(struct device *dev, struct mmc_host *mmc) | ||
| 242 | { | ||
| 243 | return 0; | ||
| 244 | } | ||
| 245 | |||
| 246 | #endif | ||
| 247 | |||
| 248 | static int sdhci_acpi_probe(struct platform_device *pdev) | 197 | static int sdhci_acpi_probe(struct platform_device *pdev) |
| 249 | { | 198 | { |
| 250 | struct device *dev = &pdev->dev; | 199 | struct device *dev = &pdev->dev; |
| @@ -332,15 +281,19 @@ static int sdhci_acpi_probe(struct platform_device *pdev) | |||
| 332 | 281 | ||
| 333 | host->mmc->caps2 |= MMC_CAP2_NO_PRESCAN_POWERUP; | 282 | host->mmc->caps2 |= MMC_CAP2_NO_PRESCAN_POWERUP; |
| 334 | 283 | ||
| 335 | err = sdhci_add_host(host); | ||
| 336 | if (err) | ||
| 337 | goto err_free; | ||
| 338 | |||
| 339 | if (sdhci_acpi_flag(c, SDHCI_ACPI_SD_CD)) { | 284 | if (sdhci_acpi_flag(c, SDHCI_ACPI_SD_CD)) { |
| 340 | if (sdhci_acpi_add_own_cd(dev, host->mmc)) | 285 | bool v = sdhci_acpi_flag(c, SDHCI_ACPI_SD_CD_OVERRIDE_LEVEL); |
| 286 | |||
| 287 | if (mmc_gpiod_request_cd(host->mmc, NULL, 0, v, 0)) { | ||
| 288 | dev_warn(dev, "failed to setup card detect gpio\n"); | ||
| 341 | c->use_runtime_pm = false; | 289 | c->use_runtime_pm = false; |
| 290 | } | ||
| 342 | } | 291 | } |
| 343 | 292 | ||
| 293 | err = sdhci_add_host(host); | ||
| 294 | if (err) | ||
| 295 | goto err_free; | ||
| 296 | |||
| 344 | if (c->use_runtime_pm) { | 297 | if (c->use_runtime_pm) { |
| 345 | pm_runtime_set_active(dev); | 298 | pm_runtime_set_active(dev); |
| 346 | pm_suspend_ignore_children(dev, 1); | 299 | pm_suspend_ignore_children(dev, 1); |
