#define ESDHC_FLAG_DUMMY_PAD BIT(19)
#define ESDHC_AUTO_TUNING_WINDOW 3
+/* 100ms timeout for data inhibit */
+#define ESDHC_DATA_INHIBIT_WAIT_US 100000
enum wp_types {
ESDHC_WP_NONE, /* no WP, neither controller nor gpio */
static void esdhc_reset(struct sdhci_host *host, u8 mask)
{
+ u32 present_state;
+ int ret;
+
+ /*
+ * For data or full reset, ensure any active data transfer completes
+ * before resetting to avoid system hang.
+ */
+ if (mask & (SDHCI_RESET_DATA | SDHCI_RESET_ALL)) {
+ ret = readl_poll_timeout_atomic(host->ioaddr + ESDHC_PRSSTAT, present_state,
+ !(present_state & SDHCI_DATA_INHIBIT), 2,
+ ESDHC_DATA_INHIBIT_WAIT_US);
+ if (ret == -ETIMEDOUT)
+ dev_warn(mmc_dev(host->mmc),
+ "timeout waiting for data transfer completion\n");
+ }
+
sdhci_and_cqhci_reset(host, mask);
sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);