summaryrefslogtreecommitdiffstats
path: root/drivers/mci/sdhci.c
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2023-03-21 10:50:56 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2023-04-05 11:54:37 +0200
commitde309f3b50ce10ac5838a6e96443acc42dee5eb6 (patch)
treebe822b035de396cef6555ad8eaa7dadf078c746a /drivers/mci/sdhci.c
parent7f013062c212078c83f85ecc1ce5329d6d9d487c (diff)
downloadbarebox-de309f3b50ce10ac5838a6e96443acc42dee5eb6.tar.gz
barebox-de309f3b50ce10ac5838a6e96443acc42dee5eb6.tar.xz
mci: sdhci: Add and use common sdhci_wait_for_done()
We have different driver specific variants of functions polling for the device ready in the tree. Add a common sdhci_wait_for_done() and use it where appropriate. This fixes a few deficiencies with the driver specific variants. rk_sdhci_wait_for_done() didn't check the SDHCI_INT_TIMEOUT bit and returned -EPERM instead when it ought to return -ETIMEDOUT. The core tries to detect a SD card first and expects a -ETIMEDOUT for the setup command when really a eMMC is connected. Only with a -ETIMEDOUT the core tries to detect a eMMC next. at91_sdhci_wait_for_done() returned the status instead of the expected 0 value for success. Link: https://lore.barebox.org/20230321095056.1333669-1-s.hauer@pengutronix.de Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'drivers/mci/sdhci.c')
-rw-r--r--drivers/mci/sdhci.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/drivers/mci/sdhci.c b/drivers/mci/sdhci.c
index 2cdd3c3c8f..635884e2a2 100644
--- a/drivers/mci/sdhci.c
+++ b/drivers/mci/sdhci.c
@@ -124,6 +124,33 @@ void sdhci_set_bus_width(struct sdhci *host, int width)
#endif
+int sdhci_wait_for_done(struct sdhci *sdhci, u32 mask)
+{
+ u64 start = get_time_ns();
+ u32 stat;
+
+ do {
+ stat = sdhci_read32(sdhci, SDHCI_INT_STATUS);
+
+ if (stat & SDHCI_INT_TIMEOUT)
+ return -ETIMEDOUT;
+
+ if (stat & SDHCI_INT_ERROR) {
+ dev_err(sdhci->mci->hw_dev, "SDHCI_INT_ERROR: 0x%08x\n",
+ stat);
+ return -EPERM;
+ }
+
+ if (is_timeout(start, 1000 * MSECOND)) {
+ dev_err(sdhci->mci->hw_dev,
+ "SDHCI timeout while waiting for done\n");
+ return -ETIMEDOUT;
+ }
+ } while ((stat & mask) != mask);
+
+ return 0;
+}
+
void sdhci_setup_data_pio(struct sdhci *sdhci, struct mci_data *data)
{
if (!data)