--- /dev/null
+From c4dedaaeb3f78d3718e9c1b1e4d972a6b99073cd Mon Sep 17 00:00:00 2001
+From: Ben Chuang <ben.chuang@genesyslogic.com.tw>
+Date: Fri, 25 Oct 2024 14:00:17 +0800
+Subject: mmc: sdhci-pci-gli: GL9767: Fix low power mode in the SD Express process
+
+From: Ben Chuang <ben.chuang@genesyslogic.com.tw>
+
+commit c4dedaaeb3f78d3718e9c1b1e4d972a6b99073cd upstream.
+
+When starting the SD Express process, the low power negotiation mode will
+be disabled, so we need to re-enable it after switching back to SD mode.
+
+Fixes: 0e92aec2efa0 ("mmc: sdhci-pci-gli: Add support SD Express card for GL9767")
+Signed-off-by: Ben Chuang <ben.chuang@genesyslogic.com.tw>
+Cc: stable@vger.kernel.org
+Message-ID: <20241025060017.1663697-2-benchuanggli@gmail.com>
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/mmc/host/sdhci-pci-gli.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/mmc/host/sdhci-pci-gli.c
++++ b/drivers/mmc/host/sdhci-pci-gli.c
+@@ -1068,6 +1068,9 @@ static int gl9767_init_sd_express(struct
+ sdhci_writew(host, value, SDHCI_CLOCK_CONTROL);
+ }
+
++ pci_read_config_dword(pdev, PCIE_GLI_9767_CFG, &value);
++ value &= ~PCIE_GLI_9767_CFG_LOW_PWR_OFF;
++ pci_write_config_dword(pdev, PCIE_GLI_9767_CFG, value);
+ gl9767_vhs_read(pdev);
+
+ return 0;
--- /dev/null
+From 8c68b5656e55e9324875881f1000eb4ee3603a87 Mon Sep 17 00:00:00 2001
+From: Ben Chuang <ben.chuang@genesyslogic.com.tw>
+Date: Fri, 25 Oct 2024 14:00:16 +0800
+Subject: mmc: sdhci-pci-gli: GL9767: Fix low power mode on the set clock function
+
+From: Ben Chuang <ben.chuang@genesyslogic.com.tw>
+
+commit 8c68b5656e55e9324875881f1000eb4ee3603a87 upstream.
+
+On sdhci_gl9767_set_clock(), the vendor header space(VHS) is read-only
+after calling gl9767_disable_ssc_pll() and gl9767_set_ssc_pll_205mhz().
+So the low power negotiation mode cannot be enabled again.
+Introduce gl9767_set_low_power_negotiation() function to fix it.
+
+The explanation process is as below.
+
+static void sdhci_gl9767_set_clock()
+{
+ ...
+ gl9767_vhs_write();
+ ...
+ value |= PCIE_GLI_9767_CFG_LOW_PWR_OFF;
+ pci_write_config_dword(pdev, PCIE_GLI_9767_CFG, value); <--- (a)
+
+ gl9767_disable_ssc_pll(); <--- (b)
+ sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
+
+ if (clock == 0)
+ return; <-- (I)
+
+ ...
+ if (clock == 200000000 && ios->timing == MMC_TIMING_UHS_SDR104) {
+ ...
+ gl9767_set_ssc_pll_205mhz(); <--- (c)
+ }
+ ...
+ value &= ~PCIE_GLI_9767_CFG_LOW_PWR_OFF;
+ pci_write_config_dword(pdev, PCIE_GLI_9767_CFG, value); <-- (II)
+ gl9767_vhs_read();
+}
+
+(a) disable low power negotiation mode. When return on (I), the low power
+mode is disabled. After (b) and (c), VHS is read-only, the low power mode
+cannot be enabled on (II).
+
+Reported-by: Georg Gottleuber <ggo@tuxedocomputers.com>
+Fixes: d2754355512e ("mmc: sdhci-pci-gli: Set SDR104's clock to 205MHz and enable SSC for GL9767")
+Signed-off-by: Ben Chuang <ben.chuang@genesyslogic.com.tw>
+Tested-by: Georg Gottleuber <ggo@tuxedocomputers.com>
+Cc: stable@vger.kernel.org
+Message-ID: <20241025060017.1663697-1-benchuanggli@gmail.com>
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/mmc/host/sdhci-pci-gli.c | 35 +++++++++++++++++++++--------------
+ 1 file changed, 21 insertions(+), 14 deletions(-)
+
+--- a/drivers/mmc/host/sdhci-pci-gli.c
++++ b/drivers/mmc/host/sdhci-pci-gli.c
+@@ -892,28 +892,40 @@ static void gl9767_disable_ssc_pll(struc
+ gl9767_vhs_read(pdev);
+ }
+
++static void gl9767_set_low_power_negotiation(struct pci_dev *pdev, bool enable)
++{
++ u32 value;
++
++ gl9767_vhs_write(pdev);
++
++ pci_read_config_dword(pdev, PCIE_GLI_9767_CFG, &value);
++ if (enable)
++ value &= ~PCIE_GLI_9767_CFG_LOW_PWR_OFF;
++ else
++ value |= PCIE_GLI_9767_CFG_LOW_PWR_OFF;
++ pci_write_config_dword(pdev, PCIE_GLI_9767_CFG, value);
++
++ gl9767_vhs_read(pdev);
++}
++
+ static void sdhci_gl9767_set_clock(struct sdhci_host *host, unsigned int clock)
+ {
+ struct sdhci_pci_slot *slot = sdhci_priv(host);
+ struct mmc_ios *ios = &host->mmc->ios;
+ struct pci_dev *pdev;
+- u32 value;
+ u16 clk;
+
+ pdev = slot->chip->pdev;
+ host->mmc->actual_clock = 0;
+
+- gl9767_vhs_write(pdev);
+-
+- pci_read_config_dword(pdev, PCIE_GLI_9767_CFG, &value);
+- value |= PCIE_GLI_9767_CFG_LOW_PWR_OFF;
+- pci_write_config_dword(pdev, PCIE_GLI_9767_CFG, value);
+-
++ gl9767_set_low_power_negotiation(pdev, false);
+ gl9767_disable_ssc_pll(pdev);
+ sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
+
+- if (clock == 0)
++ if (clock == 0) {
++ gl9767_set_low_power_negotiation(pdev, true);
+ return;
++ }
+
+ clk = sdhci_calc_clk(host, clock, &host->mmc->actual_clock);
+ if (clock == 200000000 && ios->timing == MMC_TIMING_UHS_SDR104) {
+@@ -922,12 +934,7 @@ static void sdhci_gl9767_set_clock(struc
+ }
+
+ sdhci_enable_clk(host, clk);
+-
+- pci_read_config_dword(pdev, PCIE_GLI_9767_CFG, &value);
+- value &= ~PCIE_GLI_9767_CFG_LOW_PWR_OFF;
+- pci_write_config_dword(pdev, PCIE_GLI_9767_CFG, value);
+-
+- gl9767_vhs_read(pdev);
++ gl9767_set_low_power_negotiation(pdev, true);
+ }
+
+ static void gli_set_9767(struct sdhci_host *host)