mmc: sdhci-pci: Fix initialization of some SD cards for Intel BYT-based controllers
commit 2970134b92 upstream.
Bus power may control card power, but the full reset done by SDHCI at
initialization 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.
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/r/20210331081752.23621-1-adrian.hunter@intel.com
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
01db7cb746
commit
6c43290972
1 changed files with 27 additions and 0 deletions
|
|
@ -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)
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue