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.c31
1 files changed, 30 insertions, 1 deletions
diff --git a/drivers/mmc/host/sdhci-pci-core.c b/drivers/mmc/host/sdhci-pci-core.c
index 9552708846ca..be19785227fe 100644
--- a/drivers/mmc/host/sdhci-pci-core.c
+++ b/drivers/mmc/host/sdhci-pci-core.c
@@ -516,6 +516,7 @@ struct intel_host {
int drv_strength;
bool d3_retune;
bool rpm_retune_ok;
+ bool needs_pwr_off;
u32 glk_rx_ctrl1;
u32 glk_tun_val;
u32 active_ltr;
@@ -643,9 +644,25 @@ out:
static void sdhci_intel_set_power(struct sdhci_host *host, unsigned char mode,
unsigned short vdd)
{
+ struct sdhci_pci_slot *slot = sdhci_priv(host);
+ struct intel_host *intel_host = sdhci_pci_priv(slot);
int cntr;
u8 reg;
+ /*
+ * Bus power may control card power, but a full reset still may not
+ * reset the power, whereas a direct write to SDHCI_POWER_CONTROL can.
+ * That might be needed to initialize correctly, if the card was left
+ * powered on previously.
+ */
+ if (intel_host->needs_pwr_off) {
+ intel_host->needs_pwr_off = false;
+ if (mode != MMC_POWER_OFF) {
+ sdhci_writeb(host, 0, SDHCI_POWER_CONTROL);
+ usleep_range(10000, 12500);
+ }
+ }
+
sdhci_set_power(host, mode, vdd);
if (mode == MMC_POWER_OFF)
@@ -958,7 +975,7 @@ static int glk_emmc_probe_slot(struct sdhci_pci_slot *slot)
slot->host->mmc->caps2 |= MMC_CAP2_CQE;
if (slot->chip->pdev->device != PCI_DEVICE_ID_INTEL_GLK_EMMC) {
- slot->host->mmc->caps2 |= MMC_CAP2_HS400_ES,
+ slot->host->mmc->caps2 |= MMC_CAP2_HS400_ES;
slot->host->mmc_host_ops.hs400_enhanced_strobe =
intel_hs400_enhanced_strobe;
slot->host->mmc->caps2 |= MMC_CAP2_CQE_DCMD;
@@ -1135,6 +1152,14 @@ static int byt_sdio_probe_slot(struct sdhci_pci_slot *slot)
return 0;
}
+static void byt_needs_pwr_off(struct sdhci_pci_slot *slot)
+{
+ struct intel_host *intel_host = sdhci_pci_priv(slot);
+ u8 reg = sdhci_readb(slot->host, SDHCI_POWER_CONTROL);
+
+ intel_host->needs_pwr_off = reg & SDHCI_POWER_ON;
+}
+
static int byt_sd_probe_slot(struct sdhci_pci_slot *slot)
{
byt_probe_slot(slot);
@@ -1152,6 +1177,8 @@ static int byt_sd_probe_slot(struct sdhci_pci_slot *slot)
slot->chip->pdev->subsystem_device == PCI_SUBDEVICE_ID_NI_78E3)
slot->host->mmc->caps2 |= MMC_CAP2_AVOID_3_3V;
+ byt_needs_pwr_off(slot);
+
return 0;
}
@@ -1903,6 +1930,8 @@ static const struct pci_device_id pci_ids[] = {
SDHCI_PCI_DEVICE(INTEL, CMLH_SD, intel_byt_sd),
SDHCI_PCI_DEVICE(INTEL, JSL_EMMC, intel_glk_emmc),
SDHCI_PCI_DEVICE(INTEL, JSL_SD, intel_byt_sd),
+ SDHCI_PCI_DEVICE(INTEL, LKF_EMMC, intel_glk_emmc),
+ SDHCI_PCI_DEVICE(INTEL, LKF_SD, intel_byt_sd),
SDHCI_PCI_DEVICE(O2, 8120, o2),
SDHCI_PCI_DEVICE(O2, 8220, o2),
SDHCI_PCI_DEVICE(O2, 8221, o2),