60 lines
2.1 KiB
Diff
60 lines
2.1 KiB
Diff
From 0829026de2b951c7401340fed9925dd7d192a65f Mon Sep 17 00:00:00 2001
|
|
From: Andrey Skvortsov
|
|
Date: Sat, 15 Jan 2022 15:14:46 +0300
|
|
Subject: mmc: core: Wait for command setting 'Power Off Notification' bit to
|
|
complete
|
|
|
|
SD card is allowed to signal busy on DAT0 up to 1s after the
|
|
CMD49. According to SD spec (version 6.0 section 5.8.1.3) first host
|
|
waits until busy of CMD49 is released and only then polls Power
|
|
Management Status register up to 1s until the card indicates ready to
|
|
power off.
|
|
|
|
Without waiting for busy before polling status register sometimes card
|
|
becomes unresponsive and system fails to suspend:
|
|
|
|
[ 205.907459] Freezing remaining freezable tasks ... (elapsed 0.001 seconds) done.
|
|
[ 206.421274] sunxi-mmc 1c0f000.mmc: data error, sending stop command
|
|
[ 206.421321] sunxi-mmc 1c0f000.mmc: send stop command failed
|
|
[ 206.421347] mmc0: error -110 reading status reg of PM func
|
|
[ 206.421366] PM: dpm_run_callback(): mmc_bus_suspend+0x0/0x74 returns -110
|
|
[ 206.421402] mmcblk mmc0:aaaa: PM: failed to suspend async: error -110
|
|
[ 206.437064] PM: Some devices failed to suspend, or early wake event detected
|
|
|
|
Tested with Sandisk Extreme PRO A2 64GB on Allwinner A64 system.
|
|
|
|
Signed-off-by: Andrey Skvortsov <andrej.skvortzov@gmail.com>
|
|
---
|
|
drivers/mmc/core/sd.c | 9 ++++++++-
|
|
1 file changed, 8 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
|
|
index c9db24e16af1..baaa37f22873 100644
|
|
--- a/drivers/mmc/core/sd.c
|
|
+++ b/drivers/mmc/core/sd.c
|
|
@@ -67,7 +67,7 @@ static const unsigned int sd_au_size[] = {
|
|
__res & __mask; \
|
|
})
|
|
|
|
-#define SD_POWEROFF_NOTIFY_TIMEOUT_MS 2000
|
|
+#define SD_POWEROFF_NOTIFY_TIMEOUT_MS 1000
|
|
#define SD_WRITE_EXTR_SINGLE_TIMEOUT_MS 1000
|
|
|
|
struct sd_busy_data {
|
|
@@ -1664,6 +1664,13 @@ static int sd_poweroff_notify(struct mmc_card *card)
|
|
goto out;
|
|
}
|
|
|
|
+ /* Find out when the command is completed. */
|
|
+ err = mmc_poll_for_busy(card, SD_POWEROFF_NOTIFY_TIMEOUT_MS, false,
|
|
+ MMC_BUSY_EXTR_SINGLE);
|
|
+
|
|
+ if (err)
|
|
+ goto out;
|
|
+
|
|
cb_data.card = card;
|
|
cb_data.reg_buf = reg_buf;
|
|
err = __mmc_poll_for_busy(card, SD_POWEROFF_NOTIFY_TIMEOUT_MS,
|
|
--
|
|
cgit v1.2.3
|