--- /dev/null
+From 2aa3d826adb578b26629a79b775a552cfe3fedf7 Mon Sep 17 00:00:00 2001
+From: Yangbo Lu <yangbo.lu@nxp.com>
+Date: Wed, 8 Jan 2020 12:07:12 +0800
+Subject: mmc: sdhci-of-esdhc: fix esdhc_reset() for different controller versions
+
+From: Yangbo Lu <yangbo.lu@nxp.com>
+
+commit 2aa3d826adb578b26629a79b775a552cfe3fedf7 upstream.
+
+This patch is to fix operating in esdhc_reset() for different
+controller versions, and to add bus-width restoring after data
+reset for eSDHC (verdor version <= 2.2).
+
+Also add annotation for understanding.
+
+Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
+Acked-by: Adrian Hunter <adrian.hunter@intel.com>
+Link: https://lore.kernel.org/r/20200108040713.38888-1-yangbo.lu@nxp.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/mmc/host/sdhci-of-esdhc.c | 43 ++++++++++++++++++++++++++++++++++----
+ 1 file changed, 39 insertions(+), 4 deletions(-)
+
+--- a/drivers/mmc/host/sdhci-of-esdhc.c
++++ b/drivers/mmc/host/sdhci-of-esdhc.c
+@@ -734,23 +734,58 @@ static void esdhc_reset(struct sdhci_hos
+ {
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+ struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host);
+- u32 val;
++ u32 val, bus_width = 0;
+
++ /*
++ * Add delay to make sure all the DMA transfers are finished
++ * for quirk.
++ */
+ if (esdhc->quirk_delay_before_data_reset &&
+ (mask & SDHCI_RESET_DATA) &&
+ (host->flags & SDHCI_REQ_USE_DMA))
+ mdelay(5);
+
++ /*
++ * Save bus-width for eSDHC whose vendor version is 2.2
++ * or lower for data reset.
++ */
++ if ((mask & SDHCI_RESET_DATA) &&
++ (esdhc->vendor_ver <= VENDOR_V_22)) {
++ val = sdhci_readl(host, ESDHC_PROCTL);
++ bus_width = val & ESDHC_CTRL_BUSWIDTH_MASK;
++ }
++
+ sdhci_reset(host, mask);
+
+- sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
+- sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
++ /*
++ * Restore bus-width setting and interrupt registers for eSDHC
++ * whose vendor version is 2.2 or lower for data reset.
++ */
++ if ((mask & SDHCI_RESET_DATA) &&
++ (esdhc->vendor_ver <= VENDOR_V_22)) {
++ val = sdhci_readl(host, ESDHC_PROCTL);
++ val &= ~ESDHC_CTRL_BUSWIDTH_MASK;
++ val |= bus_width;
++ sdhci_writel(host, val, ESDHC_PROCTL);
++
++ sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
++ sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
++ }
+
+- if (mask & SDHCI_RESET_ALL) {
++ /*
++ * Some bits have to be cleaned manually for eSDHC whose spec
++ * version is higher than 3.0 for all reset.
++ */
++ if ((mask & SDHCI_RESET_ALL) &&
++ (esdhc->spec_ver >= SDHCI_SPEC_300)) {
+ val = sdhci_readl(host, ESDHC_TBCTL);
+ val &= ~ESDHC_TB_EN;
+ sdhci_writel(host, val, ESDHC_TBCTL);
+
++ /*
++ * Initialize eSDHC_DLLCFG1[DLL_PD_PULSE_STRETCH_SEL] to
++ * 0 for quirk.
++ */
+ if (esdhc->quirk_unreliable_pulse_detection) {
+ val = sdhci_readl(host, ESDHC_DLLCFG1);
+ val &= ~ESDHC_DLL_PD_PULSE_STRETCH_SEL;