summaryrefslogtreecommitdiff
path: root/drivers/mmc/sdhci.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mmc/sdhci.c')
-rw-r--r--drivers/mmc/sdhci.c20
1 files changed, 20 insertions, 0 deletions
diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c
index 03bfd9d18a..766e4a6b0c 100644
--- a/drivers/mmc/sdhci.c
+++ b/drivers/mmc/sdhci.c
@@ -780,6 +780,25 @@ static int sdhci_get_cd(struct udevice *dev)
return value;
}
+static int sdhci_wait_dat0(struct udevice *dev, int state,
+ int timeout_us)
+{
+ int tmp;
+ struct mmc *mmc = mmc_get_mmc_dev(dev);
+ struct sdhci_host *host = mmc->priv;
+ unsigned long timeout = timer_get_us() + timeout_us;
+
+ // readx_poll_timeout is unsuitable because sdhci_readl accepts
+ // two arguments
+ do {
+ tmp = sdhci_readl(host, SDHCI_PRESENT_STATE);
+ if (!!(tmp & SDHCI_DATA_0_LVL_MASK) == !!state)
+ return 0;
+ } while (!timeout_us || !time_after(timer_get_us(), timeout));
+
+ return -ETIMEDOUT;
+}
+
const struct dm_mmc_ops sdhci_ops = {
.send_cmd = sdhci_send_command,
.set_ios = sdhci_set_ios,
@@ -788,6 +807,7 @@ const struct dm_mmc_ops sdhci_ops = {
#ifdef MMC_SUPPORTS_TUNING
.execute_tuning = sdhci_execute_tuning,
#endif
+ .wait_dat0 = sdhci_wait_dat0,
};
#else
static const struct mmc_ops sdhci_ops = {