.datalength_bits        = 25,
        .datactrl_blocksz       = 14,
        .stm32_idmabsize_mask   = GENMASK(12, 5),
+       .busy_timeout           = true,
+       .busy_detect            = true,
+       .busy_detect_flag       = MCI_STM32_BUSYD0,
+       .busy_detect_mask       = MCI_STM32_BUSYD0ENDMASK,
        .init                   = sdmmc_variant_init,
 };
 
 
        return datactrl;
 }
 
+static bool sdmmc_busy_complete(struct mmci_host *host, u32 status, u32 err_msk)
+{
+       void __iomem *base = host->base;
+       u32 busy_d0, busy_d0end, mask, sdmmc_status;
+
+       mask = readl_relaxed(base + MMCIMASK0);
+       sdmmc_status = readl_relaxed(base + MMCISTATUS);
+       busy_d0end = sdmmc_status & MCI_STM32_BUSYD0END;
+       busy_d0 = sdmmc_status & MCI_STM32_BUSYD0;
+
+       /* complete if there is an error or busy_d0end */
+       if ((status & err_msk) || busy_d0end)
+               goto complete;
+
+       /*
+        * On response the busy signaling is reflected in the BUSYD0 flag.
+        * if busy_d0 is in-progress we must activate busyd0end interrupt
+        * to wait this completion. Else this request has no busy step.
+        */
+       if (busy_d0) {
+               if (!host->busy_status) {
+                       writel_relaxed(mask | host->variant->busy_detect_mask,
+                                      base + MMCIMASK0);
+                       host->busy_status = status &
+                               (MCI_CMDSENT | MCI_CMDRESPEND);
+               }
+               return false;
+       }
+
+complete:
+       if (host->busy_status) {
+               writel_relaxed(mask & ~host->variant->busy_detect_mask,
+                              base + MMCIMASK0);
+               writel_relaxed(host->variant->busy_detect_mask,
+                              base + MMCICLEAR);
+               host->busy_status = 0;
+       }
+
+       return true;
+}
+
 static struct mmci_host_ops sdmmc_variant_ops = {
        .validate_data = sdmmc_idma_validate_data,
        .prep_data = sdmmc_idma_prep_data,
        .dma_finalize = sdmmc_idma_finalize,
        .set_clkreg = mmci_sdmmc_set_clkreg,
        .set_pwrreg = mmci_sdmmc_set_pwrreg,
+       .busy_complete = sdmmc_busy_complete,
 };
 
 void sdmmc_variant_init(struct mmci_host *host)