From 9b1c779d86f5cb01d5e2626add3dc322bd4625c7 Mon Sep 17 00:00:00 2001 From: Victor Shih Date: Fri, 18 Oct 2024 18:53:22 +0800 Subject: [PATCH] mmc: sdhci-uhs2: add reset function Sdhci_uhs2_reset() does a UHS-II specific reset operation. Signed-off-by: Ben Chuang Signed-off-by: AKASHI Takahiro Signed-off-by: Victor Shih Acked-by: Adrian Hunter Message-ID: <20241018105333.4569-6-victorshihgli@gmail.com> Signed-off-by: Ulf Hansson --- drivers/mmc/host/sdhci-uhs2.c | 37 +++++++++++++++++++++++++++++++++++ drivers/mmc/host/sdhci-uhs2.h | 1 + 2 files changed, 38 insertions(+) diff --git a/drivers/mmc/host/sdhci-uhs2.c b/drivers/mmc/host/sdhci-uhs2.c index 14514710e763..71c60952a40a 100644 --- a/drivers/mmc/host/sdhci-uhs2.c +++ b/drivers/mmc/host/sdhci-uhs2.c @@ -10,7 +10,9 @@ * Author: AKASHI Takahiro */ +#include #include +#include #include "sdhci.h" #include "sdhci-uhs2.h" @@ -21,6 +23,8 @@ #define SDHCI_UHS2_DUMP(f, x...) \ pr_err("%s: " DRIVER_NAME ": " f, mmc_hostname(host->mmc), ## x) +#define UHS2_RESET_TIMEOUT_100MS 100000 + void sdhci_uhs2_dump_regs(struct sdhci_host *host) { if (!(mmc_card_uhs2(host->mmc))) @@ -49,6 +53,39 @@ void sdhci_uhs2_dump_regs(struct sdhci_host *host) } EXPORT_SYMBOL_GPL(sdhci_uhs2_dump_regs); +/*****************************************************************************\ + * * + * Low level functions * + * * +\*****************************************************************************/ + +/** + * sdhci_uhs2_reset - invoke SW reset + * @host: SDHCI host + * @mask: Control mask + * + * Invoke SW reset, depending on a bit in @mask and wait for completion. + */ +void sdhci_uhs2_reset(struct sdhci_host *host, u16 mask) +{ + u32 val; + + sdhci_writew(host, mask, SDHCI_UHS2_SW_RESET); + + if (mask & SDHCI_UHS2_SW_RESET_FULL) + host->clock = 0; + + /* hw clears the bit when it's done */ + if (read_poll_timeout_atomic(sdhci_readw, val, !(val & mask), 10, + UHS2_RESET_TIMEOUT_100MS, true, host, SDHCI_UHS2_SW_RESET)) { + pr_warn("%s: %s: Reset 0x%x never completed. %s: clean reset bit.\n", __func__, + mmc_hostname(host->mmc), (int)mask, mmc_hostname(host->mmc)); + sdhci_writeb(host, 0, SDHCI_UHS2_SW_RESET); + return; + } +} +EXPORT_SYMBOL_GPL(sdhci_uhs2_reset); + /*****************************************************************************\ * * * Driver init/exit * diff --git a/drivers/mmc/host/sdhci-uhs2.h b/drivers/mmc/host/sdhci-uhs2.h index 04d75160b684..bc8395a9abda 100644 --- a/drivers/mmc/host/sdhci-uhs2.h +++ b/drivers/mmc/host/sdhci-uhs2.h @@ -175,5 +175,6 @@ struct sdhci_host; void sdhci_uhs2_dump_regs(struct sdhci_host *host); +void sdhci_uhs2_reset(struct sdhci_host *host, u16 mask); #endif /* __SDHCI_UHS2_H */ -- 2.50.1