Skip to content

Commit

Permalink
mmc: core: Wait for command setting 'Power Off Notification' bit to c…
Browse files Browse the repository at this point in the history
…omplete

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>
Fixes: 2c5d427 ("mmc: core: Add support for Power Off Notification for SD cards")
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/r/20220115121447.641524-1-andrej.skvortzov@gmail.com
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
  • Loading branch information
Andrey Skvortsov authored and Ulf Hansson committed Jan 24, 2022
1 parent 4d31535 commit 379f56c
Showing 1 changed file with 7 additions and 1 deletion.
8 changes: 7 additions & 1 deletion drivers/mmc/core/sd.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -1664,6 +1664,12 @@ 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_WRITE_EXTR_SINGLE_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->host, SD_POWEROFF_NOTIFY_TIMEOUT_MS,
Expand Down

0 comments on commit 379f56c

Please sign in to comment.