diff mbox series

[v3,2/2] mmc: host: msm: Disable auto-cmd12 during ffu

Message ID 20231025113035.1881418-3-avri.altman@wdc.com (mailing list archive)
State New, archived
Headers show
Series mmc: host: Disable auto-cmd12 during ffu | expand

Commit Message

Avri Altman Oct. 25, 2023, 11:30 a.m. UTC
Some platforms generate auto command error interrupt when it shouldn't,
e.g. auto-cmd12 while in close-ended ffu sequence.

I encounterd this issue while testing fwup on HP Chromebook x2, qualcomm
based QC-7c, code name for board - strongbad.

Instead of a quirk, hook the request function of the msm ops, so it'll
disable auto-cmd12 while close-ended ffu is in progress.

Signed-off-by: Avri Altman <avri.altman@wdc.com>
---
 drivers/mmc/host/sdhci-msm.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)
diff mbox series

Patch

diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
index 668e0aceeeba..99d6cac335a4 100644
--- a/drivers/mmc/host/sdhci-msm.c
+++ b/drivers/mmc/host/sdhci-msm.c
@@ -8,6 +8,7 @@ 
 #include <linux/module.h>
 #include <linux/delay.h>
 #include <linux/mmc/mmc.h>
+#include <linux/mmc/host.h>
 #include <linux/pm_runtime.h>
 #include <linux/pm_opp.h>
 #include <linux/slab.h>
@@ -2245,6 +2246,27 @@  static int sdhci_msm_start_signal_voltage_switch(struct mmc_host *mmc,
 	return -EAGAIN;
 }
 
+static void sdhci_msm_check_auto_cmd12(struct mmc_host *mmc,
+				       struct mmc_request *mrq)
+{
+	struct sdhci_host *host = mmc_priv(mmc);
+	bool auto_cmd12 = (host->quirks & SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12);
+
+	if (mrq->data && auto_cmd12) {
+		if (mmc_is_ffu_cmd(mrq->cmd))
+			host->flags &= ~SDHCI_AUTO_CMD12;
+		else
+			host->flags |= SDHCI_AUTO_CMD12;
+	}
+}
+
+static void sdhci_msm_request(struct mmc_host *mmc, struct mmc_request *mrq)
+{
+	sdhci_msm_check_auto_cmd12(mmc, mrq);
+
+	sdhci_request(mmc, mrq);
+}
+
 #define DRIVER_NAME "sdhci_msm"
 #define SDHCI_MSM_DUMP(f, x...) \
 	pr_err("%s: " DRIVER_NAME ": " f, mmc_hostname(host->mmc), ## x)
@@ -2638,6 +2660,8 @@  static int sdhci_msm_probe(struct platform_device *pdev)
 					 MSM_MMC_AUTOSUSPEND_DELAY_MS);
 	pm_runtime_use_autosuspend(&pdev->dev);
 
+	host->mmc_host_ops.request = sdhci_msm_request;
+
 	host->mmc_host_ops.start_signal_voltage_switch =
 		sdhci_msm_start_signal_voltage_switch;
 	host->mmc_host_ops.execute_tuning = sdhci_msm_execute_tuning;