On Thu, 2 May 2019 at 09:53, Adrian Hunter <adrian.hunter@xxxxxxxxx> wrote: > > Some time ago, a fix was done for the sdhci-acpi driver, refer > commit 6e1c7d6103fe ("mmc: sdhci-acpi: Reduce Baytrail eMMC/SD/SDIO > hangs"). The same issue was not expected to affect the sdhci-pci driver, > but there have been reports to the contrary, so make the same hardware > setting change. > > This patch applies to v5.0+ but before that backports will be required. > > Signed-off-by: Adrian Hunter <adrian.hunter@xxxxxxxxx> > Cc: stable@xxxxxxxxxxxxxxx > --- > drivers/mmc/host/Kconfig | 1 + > drivers/mmc/host/sdhci-pci-core.c | 89 +++++++++++++++++++++++++++++++ > 2 files changed, 90 insertions(+) > > diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig > index 9c01310a0d2e..d084a9d63623 100644 > --- a/drivers/mmc/host/Kconfig > +++ b/drivers/mmc/host/Kconfig > @@ -92,6 +92,7 @@ config MMC_SDHCI_PCI > tristate "SDHCI support on PCI bus" > depends on MMC_SDHCI && PCI > select MMC_CQHCI > + select IOSF_MBI if X86 > help > This selects the PCI Secure Digital Host Controller Interface. > Most controllers found today are PCI devices. > diff --git a/drivers/mmc/host/sdhci-pci-core.c b/drivers/mmc/host/sdhci-pci-core.c > index a3d7a9db76c5..64e79a19d5ad 100644 > --- a/drivers/mmc/host/sdhci-pci-core.c > +++ b/drivers/mmc/host/sdhci-pci-core.c > @@ -31,6 +31,10 @@ > #include <linux/mmc/sdhci-pci-data.h> > #include <linux/acpi.h> > > +#ifdef CONFIG_X86 > +#include <asm/iosf_mbi.h> > +#endif > + > #include "cqhci.h" > > #include "sdhci.h" > @@ -451,6 +455,50 @@ static const struct sdhci_pci_fixes sdhci_intel_pch_sdio = { > .probe_slot = pch_hc_probe_slot, > }; > > +#ifdef CONFIG_X86 > + > +#define BYT_IOSF_SCCEP 0x63 > +#define BYT_IOSF_OCP_NETCTRL0 0x1078 > +#define BYT_IOSF_OCP_TIMEOUT_BASE GENMASK(10, 8) > + > +static void byt_ocp_setting(struct pci_dev *pdev) > +{ > + u32 val = 0; > + > + if (pdev->device != PCI_DEVICE_ID_INTEL_BYT_EMMC && > + pdev->device != PCI_DEVICE_ID_INTEL_BYT_SDIO && > + pdev->device != PCI_DEVICE_ID_INTEL_BYT_SD && > + pdev->device != PCI_DEVICE_ID_INTEL_BYT_EMMC2) > + return; > + > + if (iosf_mbi_read(BYT_IOSF_SCCEP, MBI_CR_READ, BYT_IOSF_OCP_NETCTRL0, > + &val)) { > + dev_err(&pdev->dev, "%s read error\n", __func__); > + return; > + } > + > + if (!(val & BYT_IOSF_OCP_TIMEOUT_BASE)) > + return; > + > + val &= ~BYT_IOSF_OCP_TIMEOUT_BASE; > + > + if (iosf_mbi_write(BYT_IOSF_SCCEP, MBI_CR_WRITE, BYT_IOSF_OCP_NETCTRL0, > + val)) { > + dev_err(&pdev->dev, "%s write error\n", __func__); > + return; > + } > + > + dev_dbg(&pdev->dev, "%s completed\n", __func__); > +} > + > +#else > + > +static inline void byt_ocp_setting(struct pci_dev *pdev) > +{ > +} > + > +#endif > + > enum { > INTEL_DSM_FNS = 0, > INTEL_DSM_V18_SWITCH = 3, > @@ -715,6 +763,8 @@ static void byt_probe_slot(struct sdhci_pci_slot *slot) > > byt_read_dsm(slot); > > + byt_ocp_setting(slot->chip->pdev); > + > ops->execute_tuning = intel_execute_tuning; > ops->start_signal_voltage_switch = intel_start_signal_voltage_switch; > > @@ -971,7 +1021,44 @@ static const struct sdhci_pci_fixes sdhci_intel_glk_emmc = { > .priv_size = sizeof(struct intel_host), > }; > > +#ifdef CONFIG_PM_SLEEP > + > +static int byt_resume(struct sdhci_pci_chip *chip) > +{ > + byt_ocp_setting(chip->pdev); > + > + return sdhci_pci_resume_host(chip); > +} > + > +#define BYT_SPM_OPS .resume = byt_resume, > + > +#else > + > +#define BYT_SPM_OPS > + > +#endif > + > +#ifdef CONFIG_PM > + > +static int byt_runtime_resume(struct sdhci_pci_chip *chip) > +{ > + byt_ocp_setting(chip->pdev); > + > + return sdhci_pci_runtime_resume_host(chip); > +} > + > +#define BYT_RPM_OPS .runtime_resume = byt_runtime_resume, > + > +#else > + > +#define BYT_RPM_OPS > + > +#endif > + > +#define BYT_PM_OPS BYT_SPM_OPS BYT_RPM_OPS This ifdef hackary is a bit too much for me. :-) Could you have the callbacks being assigned always and instead rely only on byt_ocp_setting() having different implementations, depending on if CONFIG_X86 is set or not? > + > static const struct sdhci_pci_fixes sdhci_ni_byt_sdio = { > + BYT_PM_OPS > .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC | > SDHCI_QUIRK_NO_LED, > .quirks2 = SDHCI_QUIRK2_HOST_OFF_CARD_ON | > @@ -983,6 +1070,7 @@ static const struct sdhci_pci_fixes sdhci_ni_byt_sdio = { > }; > > static const struct sdhci_pci_fixes sdhci_intel_byt_sdio = { > + BYT_PM_OPS > .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC | > SDHCI_QUIRK_NO_LED, > .quirks2 = SDHCI_QUIRK2_HOST_OFF_CARD_ON | > @@ -994,6 +1082,7 @@ static const struct sdhci_pci_fixes sdhci_intel_byt_sdio = { > }; > > static const struct sdhci_pci_fixes sdhci_intel_byt_sd = { > + BYT_PM_OPS > .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC | > SDHCI_QUIRK_NO_LED, > .quirks2 = SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON | > -- > 2.17.1 > Kind regards Uffe