summaryrefslogtreecommitdiff
path: root/drivers/mmc/host/sdhci-pci-core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mmc/host/sdhci-pci-core.c')
-rw-r--r--drivers/mmc/host/sdhci-pci-core.c53
1 files changed, 26 insertions, 27 deletions
diff --git a/drivers/mmc/host/sdhci-pci-core.c b/drivers/mmc/host/sdhci-pci-core.c
index 1f0bd723f011..c347fac24515 100644
--- a/drivers/mmc/host/sdhci-pci-core.c
+++ b/drivers/mmc/host/sdhci-pci-core.c
@@ -20,7 +20,6 @@
#include <linux/scatterlist.h>
#include <linux/io.h>
#include <linux/iopoll.h>
-#include <linux/gpio.h>
#include <linux/gpio/machine.h>
#include <linux/pm_runtime.h>
#include <linux/pm_qos.h>
@@ -152,18 +151,15 @@ static int sdhci_pci_runtime_suspend_host(struct sdhci_pci_chip *chip)
{
struct sdhci_pci_slot *slot;
struct sdhci_host *host;
- int i, ret;
- for (i = 0; i < chip->num_slots; i++) {
+ for (int i = 0; i < chip->num_slots; i++) {
slot = chip->slots[i];
if (!slot)
continue;
host = slot->host;
- ret = sdhci_runtime_suspend_host(host);
- if (ret)
- goto err_pci_runtime_suspend;
+ sdhci_runtime_suspend_host(host);
if (chip->rpm_retune &&
host->tuning_mode != SDHCI_TUNING_MODE_3)
@@ -171,26 +167,18 @@ static int sdhci_pci_runtime_suspend_host(struct sdhci_pci_chip *chip)
}
return 0;
-
-err_pci_runtime_suspend:
- while (--i >= 0)
- sdhci_runtime_resume_host(chip->slots[i]->host, 0);
- return ret;
}
static int sdhci_pci_runtime_resume_host(struct sdhci_pci_chip *chip)
{
struct sdhci_pci_slot *slot;
- int i, ret;
- for (i = 0; i < chip->num_slots; i++) {
+ for (int i = 0; i < chip->num_slots; i++) {
slot = chip->slots[i];
if (!slot)
continue;
- ret = sdhci_runtime_resume_host(slot->host, 0);
- if (ret)
- return ret;
+ sdhci_runtime_resume_host(slot->host, 0);
}
return 0;
@@ -610,8 +598,12 @@ static void sdhci_intel_set_power(struct sdhci_host *host, unsigned char mode,
sdhci_set_power(host, mode, vdd);
- if (mode == MMC_POWER_OFF)
+ if (mode == MMC_POWER_OFF) {
+ if (slot->chip->pdev->device == PCI_DEVICE_ID_INTEL_APL_SD ||
+ slot->chip->pdev->device == PCI_DEVICE_ID_INTEL_BYT_SD)
+ usleep_range(15000, 17500);
return;
+ }
/*
* Bus power might not enable after D3 -> D0 transition due to the
@@ -686,8 +678,19 @@ static int intel_start_signal_voltage_switch(struct mmc_host *mmc,
return 0;
}
+static void sdhci_intel_set_clock(struct sdhci_host *host, unsigned int clock)
+{
+ u16 clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
+
+ /* Stop card clock separately to avoid glitches on clock line */
+ if (clk & SDHCI_CLOCK_CARD_EN)
+ sdhci_writew(host, clk & ~SDHCI_CLOCK_CARD_EN, SDHCI_CLOCK_CONTROL);
+
+ sdhci_set_clock(host, clock);
+}
+
static const struct sdhci_ops sdhci_intel_byt_ops = {
- .set_clock = sdhci_set_clock,
+ .set_clock = sdhci_intel_set_clock,
.set_power = sdhci_intel_set_power,
.enable_dma = sdhci_pci_enable_dma,
.set_bus_width = sdhci_set_bus_width,
@@ -697,7 +700,7 @@ static const struct sdhci_ops sdhci_intel_byt_ops = {
};
static const struct sdhci_ops sdhci_intel_glk_ops = {
- .set_clock = sdhci_set_clock,
+ .set_clock = sdhci_intel_set_clock,
.set_power = sdhci_intel_set_power,
.enable_dma = sdhci_pci_enable_dma,
.set_bus_width = sdhci_set_bus_width,
@@ -909,7 +912,8 @@ static bool glk_broken_cqhci(struct sdhci_pci_slot *slot)
{
return slot->chip->pdev->device == PCI_DEVICE_ID_INTEL_GLK_EMMC &&
(dmi_match(DMI_BIOS_VENDOR, "LENOVO") ||
- dmi_match(DMI_SYS_VENDOR, "IRBIS"));
+ dmi_match(DMI_SYS_VENDOR, "IRBIS") ||
+ dmi_match(DMI_SYS_VENDOR, "Positivo Tecnologia SA"));
}
static bool jsl_broken_hs400es(struct sdhci_pci_slot *slot)
@@ -2169,7 +2173,7 @@ static struct sdhci_pci_slot *sdhci_pci_probe_slot(
ret = pcim_iomap_regions(pdev, BIT(bar), mmc_hostname(host->mmc));
if (ret) {
dev_err(&pdev->dev, "cannot request region\n");
- goto cleanup;
+ return ERR_PTR(ret);
}
host->ioaddr = pcim_iomap_table(pdev)[bar];
@@ -2177,7 +2181,7 @@ static struct sdhci_pci_slot *sdhci_pci_probe_slot(
if (chip->fixes && chip->fixes->probe_slot) {
ret = chip->fixes->probe_slot(slot);
if (ret)
- goto cleanup;
+ return ERR_PTR(ret);
}
host->mmc->pm_caps = MMC_PM_KEEP_POWER;
@@ -2238,9 +2242,6 @@ remove:
if (chip->fixes && chip->fixes->remove_slot)
chip->fixes->remove_slot(slot, 0);
-cleanup:
- sdhci_free_host(host);
-
return ERR_PTR(ret);
}
@@ -2261,8 +2262,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);
-
- sdhci_free_host(slot->host);
}
int sdhci_pci_uhs2_add_host(struct sdhci_pci_slot *slot)