Re: [PATCH v2 2/2] mmc: core: Add MMC_CAP2_NO_SLEEP_CMD host capability

From: Ulf Hansson

Date: Sat Jul 18 2026 - 09:51:42 EST


On Fri, Jul 17, 2026 at 8:06 PM Kamal Dasu <kamal.dasu@xxxxxxxxxxxx> wrote:
>
> Some (e)MMC devices take longer to exit the SLEEP (CMD5) state than
> their advertised S_A_TIMEOUT allows for. On platforms where a boot
> ROM sends CMD0 and reads boot code from the card immediately on
> resume, a card still asleep at that point causes the ROM to treat
> it as fatal and reset.
>
> Add MMC_CAP2_NO_SLEEP_CMD, settable via the new "no-mmc-sleep" DT
> property, so affected hosts can tell mmc_card_can_sleep() to never
> put the card to sleep, regardless of ext_csd revision. This is a
> host-level capability rather than a card quirk so it also covers
> cards whose bug can't be identified by CID/ext_csd matching alone,
> and it is resolved before the card even exists, avoiding any
> ordering dependency on when a card-quirk table would be applied.
>
> Reported-by: Florian Fainelli <florian.fainelli@xxxxxxxxxxxx>
> Closes: https://lore.kernel.org/r/20260413180551.3683969-1-florian.fainelli@xxxxxxxxxxxx/
> Signed-off-by: Kamal Dasu <kamal.dasu@xxxxxxxxxxxx>


> ---
> Changes in v2:
> - Replaced the card-level MMC_QUIRK_BROKEN_SLEEP quirk (keyed off
> CID) with a host capability, MMC_CAP2_NO_SLEEP_CMD, set from the
> new "no-mmc-sleep" DT property, per Ulf's suggestion that this
> generalize beyond one device's CID.
> - Resolving the capability in mmc_of_parse(), before any card
> exists, also addresses Oleksij's concern that a quirk registered
> in mmc_blk_fixups[] (applied at mmc_block probe time) could lose
> a race against an earlier SLEEP/poweroff on an under-voltage
> path.
> - Added Reported-by/Closes tags crediting Florian for the original
> bug report.
>
> drivers/mmc/core/host.c | 2 ++
> drivers/mmc/core/mmc.c | 3 +++
> include/linux/mmc/host.h | 1 +
> 3 files changed, 6 insertions(+)
>
> diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
> index b7ce3137d452..3bc19645ea96 100644
> --- a/drivers/mmc/core/host.c
> +++ b/drivers/mmc/core/host.c
> @@ -400,6 +400,8 @@ int mmc_of_parse(struct mmc_host *host)
> if (device_property_read_bool(dev, "no-mmc-hs400"))
> host->caps2 &= ~(MMC_CAP2_HS400_1_8V | MMC_CAP2_HS400_1_2V |
> MMC_CAP2_HS400_ES);
> + if (device_property_read_bool(dev, "no-mmc-sleep"))
> + host->caps2 |= MMC_CAP2_NO_SLEEP_CMD;
>
> /* Must be after "non-removable" check */
> if (device_property_read_u32(dev, "fixed-emmc-driver-type", &drv_type) == 0) {
> diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
> index 05444ecf3909..5e80fa5c1a28 100644
> --- a/drivers/mmc/core/mmc.c
> +++ b/drivers/mmc/core/mmc.c
> @@ -1972,6 +1972,9 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
>
> static bool mmc_card_can_sleep(struct mmc_card *card)
> {
> + if (card->host->caps2 & MMC_CAP2_NO_SLEEP_CMD)
> + return false;
> +

No.

As I said several times by now, we should not just skip the sleep
command, but rather always keep the card powered on.

So, instead I suggest we look at adjusting the code in _mmc_suspend()
to cope with this.

> return card->ext_csd.rev >= 3;
> }
>
> diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
> index ba84f02c2a10..0447a8efed50 100644
> --- a/include/linux/mmc/host.h
> +++ b/include/linux/mmc/host.h
> @@ -463,6 +463,7 @@ struct mmc_host {
> #define MMC_CAP2_CRYPTO 0
> #endif
> #define MMC_CAP2_ALT_GPT_TEGRA (1 << 28) /* Host with eMMC that has GPT entry at a non-standard location */
> +#define MMC_CAP2_NO_SLEEP_CMD (1 << 29) /* Card can't reliably wake from CMD5 SLEEP */
>
> bool uhs2_sd_tran; /* UHS-II flag for SD_TRAN state */
> bool uhs2_app_cmd; /* UHS-II flag for APP command */
> --
> 2.34.1
>

Kind regards
Uffe