* [PATCH v4 0/2] mmc: core: Keep the card powered across suspend when firmware needs it live
@ 2026-07-28 19:03 Kamal Dasu
2026-07-28 19:03 ` [PATCH v4 1/2] dt-bindings: mmc: Extend keep-power-in-suspend beyond SDIO Kamal Dasu
2026-07-28 19:03 ` [PATCH v4 2/2] mmc: core: Honor keep-power-in-suspend for (e)MMC in suspend/resume Kamal Dasu
0 siblings, 2 replies; 5+ messages in thread
From: Kamal Dasu @ 2026-07-28 19:03 UTC (permalink / raw)
To: Ulf Hansson
Cc: Kamal Dasu, Florian Fainelli, Wolfram Sang, Oleksij Rempel,
Avri Altman, Pedro Demarchi Gomes, Erick Shepherd, Adrian Hunter,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, linux-mmc,
devicetree, linux-kernel
This is v4.
Background: on brcmstb boards with a Kioxia 016G01 eMMC, firmware
accesses the card directly during resume from Suspend-to-DRAM, before
the kernel's own resume path runs, in order to load boot code using
hard wired logic that is not field updatable. The card needs to stay
powered and responsive for that access to succeed.
Changes in v4:
- Dropped the no-mmc-poweroff-suspend DT property and
MMC_CAP2_NO_POWEROFF_SUSPEND host capability entirely. Krzysztof
pointed out they described exactly the same contract as the
existing keep-power-in-suspend property (don't power off the card
across suspend/resume). Extended keep-power-in-suspend's scope
beyond SDIO instead, and reworked _mmc_suspend() to check
host->pm_caps & MMC_PM_KEEP_POWER directly rather than adding a
new capability. (e)MMC has no per-function driver to make the
dynamic sdio_set_host_pm_flags() request SDIO uses, so this reads
pm_caps -- the DT-derived, fixed platform characteristic -- not
pm_flags.
- Gated the fast path on pm_type == MMC_POWEROFF_SUSPEND; it was
previously unconditional, so it wrongly skipped the required
power-off/notify handling during shutdown, unbind and
undervoltage as well.
- Reset the host to its initial bus state (mmc_set_clock() +
mmc_set_initial_state(), the same helpers _mmc_hw_reset() uses for
a non-power-cycle reset) before marking the card suspended.
- Set/clear host->pm_flags |= MMC_PM_KEEP_POWER around the suspend/
resume, mirroring the SDIO convention, so host drivers can tell
power was preserved if they need to.
Changes in v3:
- Reworked the fix in _mmc_suspend() (drivers/mmc/core/mmc.c) to
skip the poweroff-notify/sleep/power-off sequence entirely.
- Renamed no-mmc-sleep/MMC_CAP2_NO_SLEEP_CMD to
no-mmc-poweroff-suspend/MMC_CAP2_NO_POWEROFF_SUSPEND.
Changes in v2:
- Replaced v1's card-level MMC_QUIRK_BROKEN_SLEEP quirk with a host
capability and matching DT property, per Ulf's suggestion.
- Added Reported-by/Closes tags crediting Florian.
Kamal Dasu (2):
dt-bindings: mmc: Extend keep-power-in-suspend beyond SDIO
mmc: core: Honor keep-power-in-suspend for (e)MMC in suspend/resume
.../bindings/mmc/mmc-controller-common.yaml | 7 ++++-
drivers/mmc/core/mmc.c | 30 ++++++++++++++++++++++
2 files changed, 36 insertions(+), 1 deletion(-)
--
2.34.1
^ permalink raw reply [flat|nested] 5+ messages in thread* [PATCH v4 1/2] dt-bindings: mmc: Extend keep-power-in-suspend beyond SDIO 2026-07-28 19:03 [PATCH v4 0/2] mmc: core: Keep the card powered across suspend when firmware needs it live Kamal Dasu @ 2026-07-28 19:03 ` Kamal Dasu 2026-07-28 19:16 ` sashiko-bot 2026-07-28 19:03 ` [PATCH v4 2/2] mmc: core: Honor keep-power-in-suspend for (e)MMC in suspend/resume Kamal Dasu 1 sibling, 1 reply; 5+ messages in thread From: Kamal Dasu @ 2026-07-28 19:03 UTC (permalink / raw) To: Ulf Hansson Cc: Kamal Dasu, Florian Fainelli, Wolfram Sang, Oleksij Rempel, Avri Altman, Pedro Demarchi Gomes, Erick Shepherd, Adrian Hunter, Rob Herring, Krzysztof Kozlowski, Conor Dooley, linux-mmc, devicetree, linux-kernel keep-power-in-suspend already documents exactly the requirement needed on (e)MMC platforms where firmware accesses the card directly during resume. Rather than add a separate property describing the same contract, drop its "SDIO only" restriction and document the (e)MMC use case alongside the existing SDIO one. Signed-off-by: Kamal Dasu <kamal.dasu@broadcom.com> --- Changes in v4: - Dropped no-mmc-poweroff-suspend entirely and extended keep-power-in-suspend instead, per Krzysztof: the two properties described the same "don't power off across suspend/resume" contract. Changes in v3: - Renamed from no-mmc-sleep; dropped S_A_TIMEOUT framing per Ulf. Changes in v2: - New patch, replacing v1's card-level quirk, per Ulf. Documentation/devicetree/bindings/mmc/mmc-controller-common.yaml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/mmc/mmc-controller-common.yaml b/Documentation/devicetree/bindings/mmc/mmc-controller-common.yaml index 3d7195e9461c..f4663b318435 100644 --- a/Documentation/devicetree/bindings/mmc/mmc-controller-common.yaml +++ b/Documentation/devicetree/bindings/mmc/mmc-controller-common.yaml @@ -291,7 +291,12 @@ properties: keep-power-in-suspend: $ref: /schemas/types.yaml#/definitions/flag description: - SDIO only. Preserves card power during a suspend/resume cycle. + Preserves card power during a suspend/resume cycle. For SDIO, + this is a request an individual function driver can make at + runtime via sdio_set_host_pm_flags(). For (e)MMC, it is instead + a fixed platform characteristic, needed on boards where firmware + accesses the card directly during system resume, before the + kernel's own resume path runs. wakeup-source: $ref: /schemas/types.yaml#/definitions/flag -- 2.34.1 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH v4 1/2] dt-bindings: mmc: Extend keep-power-in-suspend beyond SDIO 2026-07-28 19:03 ` [PATCH v4 1/2] dt-bindings: mmc: Extend keep-power-in-suspend beyond SDIO Kamal Dasu @ 2026-07-28 19:16 ` sashiko-bot 0 siblings, 0 replies; 5+ messages in thread From: sashiko-bot @ 2026-07-28 19:16 UTC (permalink / raw) To: Kamal Dasu; +Cc: conor+dt, robh, devicetree Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider: - [High] The `keep-power-in-suspend` DT property contract is extended to (e)MMC devices but is not implemented in the MMC core, causing cards to be incorrectly powered off during suspend. -- --- Patch [1]: [PATCH v4 1/2] dt-bindings: mmc: Extend keep-power-in-suspend beyond SDIO --- commit 586f6f073c6606f13ea85125ddb68d3d032283b3 Author: Kamal Dasu <kamal.dasu@broadcom.com> dt-bindings: mmc: Extend keep-power-in-suspend beyond SDIO This commit drops the SDIO only restriction for the keep-power-in-suspend property and documents its use for MMC devices. This allows platforms where firmware accesses the card directly during system resume to specify that card power must be preserved. > diff --git a/Documentation/devicetree/bindings/mmc/mmc-controller-common.yaml b/Documentation/devicetree/bindings/mmc/mmc-controller-common.yaml > index 3d7195e9461c3..f4663b3184355 100644 > --- a/Documentation/devicetree/bindings/mmc/mmc-controller-common.yaml > +++ b/Documentation/devicetree/bindings/mmc/mmc-controller-common.yaml > @@ -291,7 +291,12 @@ properties: > keep-power-in-suspend: > $ref: /schemas/types.yaml#/definitions/flag > description: > - SDIO only. Preserves card power during a suspend/resume cycle. > + Preserves card power during a suspend/resume cycle. For SDIO, > + this is a request an individual function driver can make at > + runtime via sdio_set_host_pm_flags(). For (e)MMC, it is instead > + a fixed platform characteristic, needed on boards where firmware > + accesses the card directly during system resume, before the > + kernel's own resume path runs. [Severity: High] Does the MMC core currently support preserving power for MMC devices during suspend to fulfill this newly documented contract? Looking at the eMMC suspend path, it unconditionally calls mmc_power_off(): drivers/mmc/core/mmc.c:_mmc_suspend() { ... if (!err) { mmc_power_off(host); mmc_card_set_suspended(host->card); } ... } The SD suspend path also unconditionally powers off the card: drivers/mmc/core/sd.c:_mmc_sd_suspend() { ... if (!err) { mmc_power_off(host); mmc_card_set_suspended(card); } ... } If a platform relies on this property because its firmware accesses the card directly during resume, wouldn't unconditionally powering it off during suspend break the system resume? Is there a missing patch in this series to update the core to check the property before calling mmc_power_off()? -- Sashiko AI review · https://sashiko.dev/#/patchset/20260728190314.2325906-1-kamal.dasu@broadcom.com?part=1 ^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v4 2/2] mmc: core: Honor keep-power-in-suspend for (e)MMC in suspend/resume 2026-07-28 19:03 [PATCH v4 0/2] mmc: core: Keep the card powered across suspend when firmware needs it live Kamal Dasu 2026-07-28 19:03 ` [PATCH v4 1/2] dt-bindings: mmc: Extend keep-power-in-suspend beyond SDIO Kamal Dasu @ 2026-07-28 19:03 ` Kamal Dasu 2026-07-28 19:15 ` sashiko-bot 1 sibling, 1 reply; 5+ messages in thread From: Kamal Dasu @ 2026-07-28 19:03 UTC (permalink / raw) To: Ulf Hansson Cc: Kamal Dasu, Florian Fainelli, Wolfram Sang, Oleksij Rempel, Avri Altman, Pedro Demarchi Gomes, Erick Shepherd, Adrian Hunter, Rob Herring, Krzysztof Kozlowski, Conor Dooley, linux-mmc, devicetree, linux-kernel On some platforms, firmware accesses the (e)MMC card directly during resume from Suspend-to-DRAM, before the kernel's own resume path has run, in order to load boot code. This requires the card to remain powered and responsive throughout suspend: putting it to sleep, sending it a power-off notification, or removing its supply is not safe, since firmware needs to talk to a live card. keep-power-in-suspend / MMC_PM_KEEP_POWER already exist for this purpose, but are only consumed in the SDIO suspend/resume path (mmc_sdio_suspend()/mmc_sdio_resume()), gated on a per-function runtime request via sdio_set_host_pm_flags(). (e)MMC has no equivalent function-driver layer to make that request, and the requirement here is a fixed platform characteristic rather than a per-cycle one, so _mmc_suspend() checks host->pm_caps directly instead of pm_flags. When pm_caps has MMC_PM_KEEP_POWER set and pm_type is MMC_POWEROFF_SUSPEND, skip the poweroff-notify/sleep/power-off sequence entirely: deselect the card, reset the host to its initial bus state the same way _mmc_hw_reset() does for a non-power-cycle reset, mark the card suspended, and set host->pm_flags |= MMC_PM_KEEP_POWER. Setting MMC_PM_KEEP_POWER in host->pm_flags during suspend ensures that host controller resume handlers are aware that card power was preserved across suspend, allowing them to perform a soft resume sequence instead of assuming power was lost. Clear this flag in _mmc_resume() upon completion. The pm_type check matters because _mmc_suspend() is also called for shutdown, driver unbind, and undervoltage, none of which are guaranteed a subsequent _mmc_resume() call, so those still need the normal power-off path. Reported-by: Florian Fainelli <florian.fainelli@broadcom.com> Closes: https://lore.kernel.org/r/20260413180551.3683969-1-florian.fainelli@broadcom.com/ Signed-off-by: Kamal Dasu <kamal.dasu@broadcom.com> --- Changes in v4: - Gated the fast path on pm_type == MMC_POWEROFF_SUSPEND; it was previously unconditional, so it wrongly skipped the required power-off/notify handling during shutdown, unbind and undervoltage as well. - Reset the host to its initial bus state (mmc_set_clock() + mmc_set_initial_state(), matching _mmc_hw_reset()'s non-power- cycle path) before marking the card suspended. - Set/clear host->pm_flags |= MMC_PM_KEEP_POWER around the suspend/ resume, mirroring the SDIO convention, so host controller resume handlers can tell power was preserved and perform a soft resume sequence instead of assuming power was lost. - Dropped MMC_CAP2_NO_POWEROFF_SUSPEND and the no-mmc-poweroff- suspend DT property entirely. Reuse keep-power-in-suspend / MMC_PM_KEEP_POWER instead, per Krzysztof's point that the new property described the same contract as the existing one. _mmc_suspend() now checks host->pm_caps directly rather than pm_flags, since (e)MMC has no per-function driver to make the dynamic sdio_set_host_pm_flags()-style request SDIO uses. Changes in v3: - Reworked _mmc_suspend() to skip poweroff-notify/sleep/power-off entirely, not just SLEEP, per Ulf. - Renamed to MMC_CAP2_NO_POWEROFF_SUSPEND/no-mmc-poweroff-suspend. Changes in v2: - Replaced the card-level MMC_QUIRK_BROKEN_SLEEP quirk with a host capability, per Ulf. - Added Reported-by/Closes crediting Florian. drivers/mmc/core/mmc.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 05444ecf3909..dff4e372ecc6 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -2157,6 +2157,35 @@ static int _mmc_suspend(struct mmc_host *host, enum mmc_poweroff_type pm_type) goto out; } + /* + * Keep the card powered across an actual suspend; shutdown, unbind + * and undervoltage still need the normal power-off path below, + * since they aren't guaranteed a subsequent _mmc_resume(). + * + * Check pm_caps, not pm_flags: unlike SDIO, (e)MMC has no + * per-function driver to request this via + * sdio_set_host_pm_flags(), so it's a fixed platform trait here. + * + * Set MMC_PM_KEEP_POWER in pm_flags so host controller drivers + * know card power was preserved during suspend and perform a + * soft resume sequence. + * + * Reset the host to its initial bus state like _mmc_hw_reset() + * does. + */ + if (pm_type == MMC_POWEROFF_SUSPEND && + (host->pm_caps & MMC_PM_KEEP_POWER)) { + host->pm_flags |= MMC_PM_KEEP_POWER; + if (!mmc_host_is_spi(host)) + err = mmc_deselect_cards(host); + if (!err) { + mmc_set_clock(host, host->f_init); + mmc_set_initial_state(host); + mmc_card_set_suspended(host->card); + } + goto out; + } + if (mmc_card_can_poweroff_notify(host->card) && mmc_host_can_poweroff_notify(host, pm_type)) err = mmc_poweroff_notify(host->card, notify_type); @@ -2220,6 +2249,7 @@ static int _mmc_resume(struct mmc_host *host) mmc_power_up(host, host->card->ocr); err = mmc_init_card(host, host->card->ocr, host->card); mmc_card_clr_suspended(host->card); + host->pm_flags &= ~MMC_PM_KEEP_POWER; out: mmc_release_host(host); -- 2.34.1 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH v4 2/2] mmc: core: Honor keep-power-in-suspend for (e)MMC in suspend/resume 2026-07-28 19:03 ` [PATCH v4 2/2] mmc: core: Honor keep-power-in-suspend for (e)MMC in suspend/resume Kamal Dasu @ 2026-07-28 19:15 ` sashiko-bot 0 siblings, 0 replies; 5+ messages in thread From: sashiko-bot @ 2026-07-28 19:15 UTC (permalink / raw) To: Kamal Dasu; +Cc: conor+dt, robh, devicetree Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider: - [High] The `MMC_PM_KEEP_POWER` flag is permanently leaked in `host->pm_flags` if the fast suspend path fails during `mmc_deselect_cards()`. -- --- Patch [2]: [PATCH v4 2/2] mmc: core: Honor keep-power-in-suspend for (e)MMC in suspend/resume --- commit 575375a652461af659583ed563eb72a97ab24900 Author: Kamal Dasu <kamal.dasu@broadcom.com> mmc: core: Honor keep-power-in-suspend for (e)MMC in suspend/resume This commit updates the core MMC code to honor the keep-power-in-suspend flag for (e)MMC devices. When this capability is present during suspend, the power-off sequence is skipped and the host is reset to its initial state instead. The MMC_PM_KEEP_POWER flag is set to inform host controllers of the preserved power state. Closes: https://lore.kernel.org/r/20260413180551.3683969-1-florian.fainelli@broadcom.com/ > diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c > --- a/drivers/mmc/core/mmc.c > +++ b/drivers/mmc/core/mmc.c [ ... ] > @@ -2157,6 +2157,35 @@ static int _mmc_suspend(struct mmc_host *host, enum mmc_poweroff_type pm_type) > goto out; > } > > + /* > + * Keep the card powered across an actual suspend; shutdown, unbind > + * and undervoltage still need the normal power-off path below, > + * since they aren't guaranteed a subsequent _mmc_resume(). > + * > + * Check pm_caps, not pm_flags: unlike SDIO, (e)MMC has no > + * per-function driver to request this via > + * sdio_set_host_pm_flags(), so it's a fixed platform trait here. > + * > + * Set MMC_PM_KEEP_POWER in pm_flags so host controller drivers > + * know card power was preserved during suspend and perform a > + * soft resume sequence. > + * > + * Reset the host to its initial bus state like _mmc_hw_reset() > + * does. > + */ > + if (pm_type == MMC_POWEROFF_SUSPEND && > + (host->pm_caps & MMC_PM_KEEP_POWER)) { > + host->pm_flags |= MMC_PM_KEEP_POWER; > + if (!mmc_host_is_spi(host)) > + err = mmc_deselect_cards(host); > + if (!err) { > + mmc_set_clock(host, host->f_init); > + mmc_set_initial_state(host); > + mmc_card_set_suspended(host->card); > + } > + goto out; > + } > + [Severity: High] Does this leak the MMC_PM_KEEP_POWER flag if mmc_deselect_cards() fails? If mmc_deselect_cards() returns an error, the function jumps to out without marking the card as suspended. [ ... ] > @@ -2220,6 +2249,7 @@ static int _mmc_resume(struct mmc_host *host) > mmc_power_up(host, host->card->ocr); > err = mmc_init_card(host, host->card->ocr, host->card); > mmc_card_clr_suspended(host->card); > + host->pm_flags &= ~MMC_PM_KEEP_POWER; > > out: > mmc_release_host(host); If the system then attempts to recover from the aborted suspend by calling _mmc_resume(), it checks if the card is suspended and exits early: _mmc_resume() { ... if (!mmc_card_suspended(host->card)) goto out; ... } Since the card was never marked suspended during the error path, it will take this goto out path and bypass the host->pm_flags cleanup, leaving MMC_PM_KEEP_POWER set permanently for the remainder of the uptime. Would it be better to clear the flag in the error path of _mmc_suspend(), or perhaps wait to set the flag until after mmc_deselect_cards() succeeds? -- Sashiko AI review · https://sashiko.dev/#/patchset/20260728190314.2325906-1-kamal.dasu@broadcom.com?part=2 ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-07-28 19:16 UTC | newest] Thread overview: 5+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-07-28 19:03 [PATCH v4 0/2] mmc: core: Keep the card powered across suspend when firmware needs it live Kamal Dasu 2026-07-28 19:03 ` [PATCH v4 1/2] dt-bindings: mmc: Extend keep-power-in-suspend beyond SDIO Kamal Dasu 2026-07-28 19:16 ` sashiko-bot 2026-07-28 19:03 ` [PATCH v4 2/2] mmc: core: Honor keep-power-in-suspend for (e)MMC in suspend/resume Kamal Dasu 2026-07-28 19:15 ` sashiko-bot
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox