diff options
Diffstat (limited to 'drivers/mmc/host/sdhci-pci-core.c')
-rw-r--r-- | drivers/mmc/host/sdhci-pci-core.c | 159 |
1 files changed, 18 insertions, 141 deletions
diff --git a/drivers/mmc/host/sdhci-pci-core.c b/drivers/mmc/host/sdhci-pci-core.c index be19785227fe..6f9877546830 100644 --- a/drivers/mmc/host/sdhci-pci-core.c +++ b/drivers/mmc/host/sdhci-pci-core.c @@ -17,8 +17,6 @@ #include <linux/dma-mapping.h> #include <linux/slab.h> #include <linux/device.h> -#include <linux/mmc/host.h> -#include <linux/mmc/mmc.h> #include <linux/scatterlist.h> #include <linux/io.h> #include <linux/iopoll.h> @@ -26,11 +24,13 @@ #include <linux/pm_runtime.h> #include <linux/pm_qos.h> #include <linux/debugfs.h> -#include <linux/mmc/slot-gpio.h> -#include <linux/mmc/sdhci-pci-data.h> #include <linux/acpi.h> #include <linux/dmi.h> +#include <linux/mmc/host.h> +#include <linux/mmc/mmc.h> +#include <linux/mmc/slot-gpio.h> + #ifdef CONFIG_X86 #include <asm/iosf_mbi.h> #endif @@ -345,73 +345,6 @@ static int pch_hc_probe_slot(struct sdhci_pci_slot *slot) return 0; } -#ifdef CONFIG_PM - -static irqreturn_t sdhci_pci_sd_cd(int irq, void *dev_id) -{ - struct sdhci_pci_slot *slot = dev_id; - struct sdhci_host *host = slot->host; - - mmc_detect_change(host->mmc, msecs_to_jiffies(200)); - return IRQ_HANDLED; -} - -static void sdhci_pci_add_own_cd(struct sdhci_pci_slot *slot) -{ - int err, irq, gpio = slot->cd_gpio; - - slot->cd_gpio = -EINVAL; - slot->cd_irq = -EINVAL; - - if (!gpio_is_valid(gpio)) - return; - - err = devm_gpio_request(&slot->chip->pdev->dev, gpio, "sd_cd"); - if (err < 0) - goto out; - - err = gpio_direction_input(gpio); - if (err < 0) - goto out_free; - - irq = gpio_to_irq(gpio); - if (irq < 0) - goto out_free; - - err = request_irq(irq, sdhci_pci_sd_cd, IRQF_TRIGGER_RISING | - IRQF_TRIGGER_FALLING, "sd_cd", slot); - if (err) - goto out_free; - - slot->cd_gpio = gpio; - slot->cd_irq = irq; - - return; - -out_free: - devm_gpio_free(&slot->chip->pdev->dev, gpio); -out: - dev_warn(&slot->chip->pdev->dev, "failed to setup card detect wake up\n"); -} - -static void sdhci_pci_remove_own_cd(struct sdhci_pci_slot *slot) -{ - if (slot->cd_irq >= 0) - free_irq(slot->cd_irq, slot); -} - -#else - -static inline void sdhci_pci_add_own_cd(struct sdhci_pci_slot *slot) -{ -} - -static inline void sdhci_pci_remove_own_cd(struct sdhci_pci_slot *slot) -{ -} - -#endif - static int mfd_emmc_probe_slot(struct sdhci_pci_slot *slot) { slot->host->mmc->caps |= MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE; @@ -619,23 +552,16 @@ static int intel_select_drive_strength(struct mmc_card *card, static int bxt_get_cd(struct mmc_host *mmc) { int gpio_cd = mmc_gpio_get_cd(mmc); - struct sdhci_host *host = mmc_priv(mmc); - unsigned long flags; - int ret = 0; if (!gpio_cd) return 0; - spin_lock_irqsave(&host->lock, flags); - - if (host->flags & SDHCI_DEVICE_DEAD) - goto out; - - ret = !!(sdhci_readl(host, SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT); -out: - spin_unlock_irqrestore(&host->lock, flags); + return sdhci_get_cd_nogpio(mmc); +} - return ret; +static int mrfld_get_cd(struct mmc_host *mmc) +{ + return sdhci_get_cd_nogpio(mmc); } #define SDHCI_INTEL_PWR_TIMEOUT_CNT 20 @@ -1341,6 +1267,14 @@ static int intel_mrfld_mmc_probe_slot(struct sdhci_pci_slot *slot) MMC_CAP_1_8V_DDR; break; case INTEL_MRFLD_SD: + slot->cd_idx = 0; + slot->cd_override_level = true; + /* + * There are two PCB designs of SD card slot with the opposite + * card detection sense. Quirk this out by ignoring GPIO state + * completely in the custom ->get_cd() callback. + */ + slot->host->mmc_host_ops.get_cd = mrfld_get_cd; slot->host->quirks2 |= SDHCI_QUIRK2_NO_1_8_V; break; case INTEL_MRFLD_SDIO: @@ -1981,21 +1915,6 @@ int sdhci_pci_enable_dma(struct sdhci_host *host) return 0; } -static void sdhci_pci_gpio_hw_reset(struct sdhci_host *host) -{ - struct sdhci_pci_slot *slot = sdhci_priv(host); - int rst_n_gpio = slot->rst_n_gpio; - - if (!gpio_is_valid(rst_n_gpio)) - return; - gpio_set_value_cansleep(rst_n_gpio, 0); - /* For eMMC, minimum is 1us but give it 10us for good measure */ - udelay(10); - gpio_set_value_cansleep(rst_n_gpio, 1); - /* For eMMC, minimum is 200us but give it 300us for good measure */ - usleep_range(300, 1000); -} - static void sdhci_pci_hw_reset(struct sdhci_host *host) { struct sdhci_pci_slot *slot = sdhci_priv(host); @@ -2126,26 +2045,8 @@ static struct sdhci_pci_slot *sdhci_pci_probe_slot( slot->chip = chip; slot->host = host; - slot->rst_n_gpio = -EINVAL; - slot->cd_gpio = -EINVAL; slot->cd_idx = -1; - /* Retrieve platform data if there is any */ - if (*sdhci_pci_get_data) - slot->data = sdhci_pci_get_data(pdev, slotno); - - if (slot->data) { - if (slot->data->setup) { - ret = slot->data->setup(slot->data); - if (ret) { - dev_err(&pdev->dev, "platform setup failed\n"); - goto free; - } - } - slot->rst_n_gpio = slot->data->rst_n_gpio; - slot->cd_gpio = slot->data->cd_gpio; - } - host->hw_name = "PCI"; host->ops = chip->fixes && chip->fixes->ops ? chip->fixes->ops : @@ -2169,17 +2070,6 @@ static struct sdhci_pci_slot *sdhci_pci_probe_slot( goto cleanup; } - if (gpio_is_valid(slot->rst_n_gpio)) { - if (!devm_gpio_request(&pdev->dev, slot->rst_n_gpio, "eMMC_reset")) { - gpio_direction_output(slot->rst_n_gpio, 1); - slot->host->mmc->caps |= MMC_CAP_HW_RESET; - slot->hw_reset = sdhci_pci_gpio_hw_reset; - } else { - dev_warn(&pdev->dev, "failed to request rst_n_gpio\n"); - slot->rst_n_gpio = -EINVAL; - } - } - host->mmc->pm_caps = MMC_PM_KEEP_POWER; host->mmc->slotno = slotno; host->mmc->caps2 |= MMC_CAP2_NO_PRESCAN_POWERUP; @@ -2214,15 +2104,11 @@ static struct sdhci_pci_slot *sdhci_pci_probe_slot( if (ret) goto remove; - sdhci_pci_add_own_cd(slot); - /* * Check if the chip needs a separate GPIO for card detect to wake up * from runtime suspend. If it is not there, don't allow runtime PM. - * Note sdhci_pci_add_own_cd() sets slot->cd_gpio to -EINVAL on failure. */ - if (chip->fixes && chip->fixes->own_cd_for_runtime_pm && - !gpio_is_valid(slot->cd_gpio) && slot->cd_idx < 0) + if (chip->fixes && chip->fixes->own_cd_for_runtime_pm && slot->cd_idx < 0) chip->allow_runtime_pm = false; return slot; @@ -2232,10 +2118,6 @@ remove: chip->fixes->remove_slot(slot, 0); cleanup: - if (slot->data && slot->data->cleanup) - slot->data->cleanup(slot->data); - -free: sdhci_free_host(host); return ERR_PTR(ret); @@ -2246,8 +2128,6 @@ static void sdhci_pci_remove_slot(struct sdhci_pci_slot *slot) int dead; u32 scratch; - sdhci_pci_remove_own_cd(slot); - dead = 0; scratch = readl(slot->host->ioaddr + SDHCI_INT_STATUS); if (scratch == (u32)-1) @@ -2258,9 +2138,6 @@ static void sdhci_pci_remove_slot(struct sdhci_pci_slot *slot) if (slot->chip->fixes && slot->chip->fixes->remove_slot) slot->chip->fixes->remove_slot(slot, dead); - if (slot->data && slot->data->cleanup) - slot->data->cleanup(slot->data); - sdhci_free_host(slot->host); } |