* [PATCH v11 0/6] mmc: core: Keep the card powered across suspend when firmware needs it live
@ 2026-10-30 18:10 Kamal Dasu
2026-10-30 18:10 ` [PATCH v11 1/6] dt-bindings: mmc: Extend keep-power-in-suspend beyond SDIO Kamal Dasu
` (5 more replies)
0 siblings, 6 replies; 8+ messages in thread
From: Kamal Dasu @ 2026-10-30 18:10 UTC (permalink / raw)
To: linux-mmc, Ulf Hansson
Cc: Ulf Hansson, Adrian Hunter, Florian Fainelli, Wolfram Sang,
Oleksij Rempel, linux-kernel, devicetree, Rob Herring,
Conor Dooley, Krzysztof Kozlowski, Krzysztof Kozlowski,
Krzysztof Kozlowski, Shawn Lin
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, and since it is never power-cycled, it also needs to be reset
before the kernel reuses it after resume.
Ulf's v10 posted patches 3-6 and I'm resending the whole series, as requested.
v10: https://lore.kernel.org/linux-mmc/20261027144051.249211-1-ulf.hansson@oss.qualcomm.com/
Changes in v11:
- Rebased on the mmc tree's next branch.
- Patch 1, 2: Resent by the author to complete the Signed-off-by
chain, with the DT list and maintainers on Cc.
- Patch 3-6: Added my Signed-off-by as the submitter.
- Patch 4: Keep the comment about suspend methods being serialized, by
moving it into mmc_set_host_pm_flags() (Shawn Lin).
- Patch 5: Also split the cache flush out of _mmc_hw_reset() into a new
mmc_hw_reset_recovery(), used for the ->hw_reset() bus op, and renamed the
patch to "Move and split reset functions for eMMC" (Ulf). The flush is
redundant when resetting at system resume, and failed with a timeout,
printing "mmc1: cache flush error -110" on every resume.
- Patch 5: Dropped Shawn's Reviewed-by as the patch changed.
- Patch 6: Claim the host around the card reset in mmc_resume(), as it
sends commands. Without it, WARN_ON(!host->claimed) triggers for every
command sent during the reset.
- Patch 6: Warn while parsing the DT properties when
reset-card-at-resume is set without keep-power-in-suspend (Ulf).
- Patch 6: Dropped Shawn's Reviewed-by as the patch changed.
Tested on a brcmstb board with the Kioxia 016G01 eMMC, using "pml -d"
(S3 suspend/resume):
keep-power-in-suspend reset-card-at-resume Result
--------------------- -------------------- ----------------------------
no no Enters suspend, board resets
at resume
yes no Enters suspend, board resets
at resume
no yes Suspend aborts, -EINVAL
yes yes S3 suspend/resume works
Kamal Dasu (2):
dt-bindings: mmc: Extend keep-power-in-suspend beyond SDIO
dt-bindings: mmc: Add reset-card-at-resume property
Ulf Hansson (4):
mmc: core: Add option to keep an eMMC powered on at system suspend
mmc: core: Split sdio_set_host_pm_flags()
mmc: core: Move and split reset functions for eMMC
mmc: core: Add support for resetting an eMMC at system resume
.../bindings/mmc/mmc-controller-common.yaml | 10 +-
drivers/mmc/core/core.c | 10 ++
drivers/mmc/core/core.h | 1 +
drivers/mmc/core/host.c | 13 +++
drivers/mmc/core/mmc.c | 105 ++++++++++++------
drivers/mmc/core/sdio_io.c | 7 +-
include/linux/mmc/host.h | 1 +
7 files changed, 105 insertions(+), 42 deletions(-)
--
2.34.1
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v11 1/6] dt-bindings: mmc: Extend keep-power-in-suspend beyond SDIO
2026-10-30 18:10 [PATCH v11 0/6] mmc: core: Keep the card powered across suspend when firmware needs it live Kamal Dasu
@ 2026-10-30 18:10 ` Kamal Dasu
2026-10-30 18:10 ` [PATCH v11 2/6] dt-bindings: mmc: Add reset-card-at-resume property Kamal Dasu
` (4 subsequent siblings)
5 siblings, 0 replies; 8+ messages in thread
From: Kamal Dasu @ 2026-10-30 18:10 UTC (permalink / raw)
To: linux-mmc, Ulf Hansson
Cc: Ulf Hansson, Adrian Hunter, Florian Fainelli, Wolfram Sang,
Oleksij Rempel, linux-kernel, devicetree, Rob Herring,
Conor Dooley, Krzysztof Kozlowski, Krzysztof Kozlowski,
Krzysztof Kozlowski, Shawn Lin
keep-power-in-suspend is currently documented as SDIO-only, but the
requirement it describes -- preserving card power across a
suspend/resume cycle -- applies just as well to any card type. Drop
the SDIO-only restriction so eMMC and SD platforms can use it too.
Signed-off-by: Kamal Dasu <kamal.dasu@broadcom.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
---
.../devicetree/bindings/mmc/mmc-controller-common.yaml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/mmc/mmc-controller-common.yaml b/Documentation/devicetree/bindings/mmc/mmc-controller-common.yaml
index 8b9b3b036129..2fc8e06d5ec9 100644
--- a/Documentation/devicetree/bindings/mmc/mmc-controller-common.yaml
+++ b/Documentation/devicetree/bindings/mmc/mmc-controller-common.yaml
@@ -301,7 +301,7 @@ 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.
wakeup-source:
$ref: /schemas/types.yaml#/definitions/flag
--
2.34.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v11 2/6] dt-bindings: mmc: Add reset-card-at-resume property
2026-10-30 18:10 [PATCH v11 0/6] mmc: core: Keep the card powered across suspend when firmware needs it live Kamal Dasu
2026-10-30 18:10 ` [PATCH v11 1/6] dt-bindings: mmc: Extend keep-power-in-suspend beyond SDIO Kamal Dasu
@ 2026-10-30 18:10 ` Kamal Dasu
2026-10-30 18:10 ` [PATCH v11 3/6] mmc: core: Add option to keep an eMMC powered on at system suspend Kamal Dasu
` (3 subsequent siblings)
5 siblings, 0 replies; 8+ messages in thread
From: Kamal Dasu @ 2026-10-30 18:10 UTC (permalink / raw)
To: linux-mmc, Ulf Hansson
Cc: Ulf Hansson, Adrian Hunter, Florian Fainelli, Wolfram Sang,
Oleksij Rempel, linux-kernel, devicetree, Rob Herring,
Conor Dooley, Krzysztof Kozlowski, Krzysztof Kozlowski,
Krzysztof Kozlowski, Shawn Lin
On some platforms, firmware or other hardware accesses the card
during suspend/resume, before the kernel's own resume path has run,
leaving the card in a state the kernel can no longer assume it knows.
Add a flag property so such boards can tell the mmc core the card
needs to be reset before it can be used again.
This is expected to be paired with keep-power-in-suspend on boards
whose firmware needs the card to stay powered and live throughout
suspend: since the card is never power-cycled, nothing else would
force it back to a known state on resume.
Signed-off-by: Kamal Dasu <kamal.dasu@broadcom.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
---
.../devicetree/bindings/mmc/mmc-controller-common.yaml | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/Documentation/devicetree/bindings/mmc/mmc-controller-common.yaml b/Documentation/devicetree/bindings/mmc/mmc-controller-common.yaml
index 2fc8e06d5ec9..c824b95f2ae2 100644
--- a/Documentation/devicetree/bindings/mmc/mmc-controller-common.yaml
+++ b/Documentation/devicetree/bindings/mmc/mmc-controller-common.yaml
@@ -303,6 +303,13 @@ properties:
description:
Preserves card power during a suspend/resume cycle.
+ reset-card-at-resume:
+ $ref: /schemas/types.yaml#/definitions/flag
+ description:
+ The HW/FW may have accessed the card during suspend/resume,
+ leaving it in an unknown state. Hence, before the card can be
+ used, it must be reset.
+
wakeup-source:
$ref: /schemas/types.yaml#/definitions/flag
description:
@@ -371,5 +378,6 @@ patternProperties:
dependencies:
cd-debounce-delay-ms: [ cd-gpios ]
fixed-emmc-driver-type: [ non-removable ]
+ reset-card-at-resume: [ keep-power-in-suspend ]
additionalProperties: true
--
2.34.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v11 3/6] mmc: core: Add option to keep an eMMC powered on at system suspend
2026-10-30 18:10 [PATCH v11 0/6] mmc: core: Keep the card powered across suspend when firmware needs it live Kamal Dasu
2026-10-30 18:10 ` [PATCH v11 1/6] dt-bindings: mmc: Extend keep-power-in-suspend beyond SDIO Kamal Dasu
2026-10-30 18:10 ` [PATCH v11 2/6] dt-bindings: mmc: Add reset-card-at-resume property Kamal Dasu
@ 2026-10-30 18:10 ` Kamal Dasu
2026-10-30 18:10 ` [PATCH v11 4/6] mmc: core: Split sdio_set_host_pm_flags() Kamal Dasu
` (2 subsequent siblings)
5 siblings, 0 replies; 8+ messages in thread
From: Kamal Dasu @ 2026-10-30 18:10 UTC (permalink / raw)
To: linux-mmc, Ulf Hansson
Cc: Ulf Hansson, Adrian Hunter, Florian Fainelli, Wolfram Sang,
Oleksij Rempel, linux-kernel, devicetree, Rob Herring,
Conor Dooley, Krzysztof Kozlowski, Krzysztof Kozlowski,
Krzysztof Kozlowski, Shawn Lin
From: Ulf Hansson <ulf.hansson@oss.qualcomm.com>
The DT property keep-power-in-suspend, allows us to specify whether the
platform is capable of keeping the power to the card during system suspend.
Up until now, this has been restricted to be used for SDIO cards only, but
let's add the initial support to allow this for eMMC too.
Signed-off-by: Ulf Hansson <ulf.hansson@oss.qualcomm.com>
Reviewed-by: Shawn Lin <shawn.lin@rock-chips.com>
Signed-off-by: Kamal Dasu <kamal.dasu@broadcom.com>
---
drivers/mmc/core/mmc.c | 24 +++++++++++++++++++++++-
1 file changed, 23 insertions(+), 1 deletion(-)
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index a02b04938e1a..c936272bcd81 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -38,6 +38,7 @@ enum mmc_poweroff_type {
MMC_POWEROFF_SHUTDOWN,
MMC_POWEROFF_UNDERVOLTAGE,
MMC_POWEROFF_UNBIND,
+ MMC_NO_POWEROFF_SUSPEND,
};
static const unsigned int tran_exp[] = {
@@ -2157,6 +2158,15 @@ static int _mmc_suspend(struct mmc_host *host, enum mmc_poweroff_type pm_type)
goto out;
}
+ if (pm_type == MMC_NO_POWEROFF_SUSPEND) {
+ if (host->retune_period) {
+ mmc_retune_timer_stop(host);
+ mmc_retune_needed(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);
@@ -2193,9 +2203,15 @@ static void mmc_remove(struct mmc_host *host)
*/
static int mmc_suspend(struct mmc_host *host)
{
+ enum mmc_poweroff_type pm_type = MMC_POWEROFF_SUSPEND;
int err;
- err = _mmc_suspend(host, MMC_POWEROFF_SUSPEND);
+ if (mmc_card_keep_power(host)) {
+ pm_runtime_resume(&host->card->dev);
+ pm_type = MMC_NO_POWEROFF_SUSPEND;
+ }
+
+ err = _mmc_suspend(host, pm_type);
if (!err) {
pm_runtime_disable(&host->card->dev);
pm_runtime_set_suspended(&host->card->dev);
@@ -2260,7 +2276,13 @@ static int mmc_shutdown(struct mmc_host *host)
*/
static int mmc_resume(struct mmc_host *host)
{
+ if (mmc_card_keep_power(host)) {
+ pm_runtime_set_active(&host->card->dev);
+ mmc_card_clr_suspended(host->card);
+ }
+
pm_runtime_enable(&host->card->dev);
+ host->pm_flags &= ~MMC_PM_KEEP_POWER;
return 0;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v11 4/6] mmc: core: Split sdio_set_host_pm_flags()
2026-10-30 18:10 [PATCH v11 0/6] mmc: core: Keep the card powered across suspend when firmware needs it live Kamal Dasu
` (2 preceding siblings ...)
2026-10-30 18:10 ` [PATCH v11 3/6] mmc: core: Add option to keep an eMMC powered on at system suspend Kamal Dasu
@ 2026-10-30 18:10 ` Kamal Dasu
2026-10-30 18:10 ` [PATCH v11 5/6] mmc: core: Move and split reset functions for eMMC Kamal Dasu
2026-10-30 18:10 ` [PATCH v11 6/6] mmc: core: Add support for resetting an eMMC at system resume Kamal Dasu
5 siblings, 0 replies; 8+ messages in thread
From: Kamal Dasu @ 2026-10-30 18:10 UTC (permalink / raw)
To: linux-mmc, Ulf Hansson
Cc: Ulf Hansson, Adrian Hunter, Florian Fainelli, Wolfram Sang,
Oleksij Rempel, linux-kernel, devicetree, Rob Herring,
Conor Dooley, Krzysztof Kozlowski, Krzysztof Kozlowski,
Krzysztof Kozlowski, Shawn Lin
From: Ulf Hansson <ulf.hansson@oss.qualcomm.com>
To prepare for a subsequent change, let's split up sdio_set_host_pm_flags()
allowing the second part of it to be used as an internal function for the
core.
Signed-off-by: Ulf Hansson <ulf.hansson@oss.qualcomm.com>
Signed-off-by: Kamal Dasu <kamal.dasu@broadcom.com>
---
drivers/mmc/core/core.c | 10 ++++++++++
drivers/mmc/core/core.h | 1 +
drivers/mmc/core/sdio_io.c | 7 +------
3 files changed, 12 insertions(+), 6 deletions(-)
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 677e445dc48c..6cbb5ee6200c 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -1422,6 +1422,16 @@ int mmc_handle_undervoltage(struct mmc_host *host)
return host->bus_ops->handle_undervoltage(host);
}
+int mmc_set_host_pm_flags(struct mmc_host *host, mmc_pm_flag_t flags)
+{
+ if (flags & ~host->pm_caps)
+ return -EINVAL;
+
+ /* function suspend methods are serialized, hence no lock needed */
+ host->pm_flags |= flags;
+ return 0;
+}
+
/*
* Assign a mmc bus handler to a host. Only one bus handler may control a
* host at any given time.
diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h
index 9be2875608ce..d3a2ff00b18f 100644
--- a/drivers/mmc/core/core.h
+++ b/drivers/mmc/core/core.h
@@ -64,6 +64,7 @@ int mmc_handle_undervoltage(struct mmc_host *host);
void mmc_regulator_register_undervoltage_notifier(struct mmc_host *host);
void mmc_regulator_unregister_undervoltage_notifier(struct mmc_host *host);
void mmc_undervoltage_workfn(struct work_struct *work);
+int mmc_set_host_pm_flags(struct mmc_host *host, mmc_pm_flag_t flags);
static inline void mmc_delay(unsigned int ms)
{
diff --git a/drivers/mmc/core/sdio_io.c b/drivers/mmc/core/sdio_io.c
index 12716ec0e35d..99f857514b63 100644
--- a/drivers/mmc/core/sdio_io.c
+++ b/drivers/mmc/core/sdio_io.c
@@ -726,12 +726,7 @@ int sdio_set_host_pm_flags(struct sdio_func *func, mmc_pm_flag_t flags)
host = func->card->host;
- if (flags & ~host->pm_caps)
- return -EINVAL;
-
- /* function suspend methods are serialized, hence no lock needed */
- host->pm_flags |= flags;
- return 0;
+ return mmc_set_host_pm_flags(host, flags);
}
EXPORT_SYMBOL_GPL(sdio_set_host_pm_flags);
--
2.34.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v11 5/6] mmc: core: Move and split reset functions for eMMC
2026-10-30 18:10 [PATCH v11 0/6] mmc: core: Keep the card powered across suspend when firmware needs it live Kamal Dasu
` (3 preceding siblings ...)
2026-10-30 18:10 ` [PATCH v11 4/6] mmc: core: Split sdio_set_host_pm_flags() Kamal Dasu
@ 2026-10-30 18:10 ` Kamal Dasu
2026-10-30 18:10 ` [PATCH v11 6/6] mmc: core: Add support for resetting an eMMC at system resume Kamal Dasu
5 siblings, 0 replies; 8+ messages in thread
From: Kamal Dasu @ 2026-10-30 18:10 UTC (permalink / raw)
To: linux-mmc, Ulf Hansson
Cc: Ulf Hansson, Adrian Hunter, Florian Fainelli, Wolfram Sang,
Oleksij Rempel, linux-kernel, devicetree, Rob Herring,
Conor Dooley, Krzysztof Kozlowski, Krzysztof Kozlowski,
Krzysztof Kozlowski, Shawn Lin
From: Ulf Hansson <ulf.hansson@oss.qualcomm.com>
To prepare for a subsequent change and to simplify review, let's move the
function for resetting the eMMC card a few lines up in the file.
While at it, split the cache flush out of _mmc_hw_reset() into a new
mmc_hw_reset_recovery() function and use that for the ->hw_reset() bus
operation. This keeps the flush for recovery, where it was intended, but
allows the card to be reset without it, by calling _mmc_hw_reset()
directly. That is needed when resetting the card at system resume, as the
cache has already been flushed at suspend and the flush would only fail
with a timeout, after the card has been accessed by firmware.
There are no functional changes.
Signed-off-by: Ulf Hansson <ulf.hansson@oss.qualcomm.com>
Co-developed-by: Kamal Dasu <kamal.dasu@broadcom.com>
Signed-off-by: Kamal Dasu <kamal.dasu@broadcom.com>
---
drivers/mmc/core/mmc.c | 73 ++++++++++++++++++++++--------------------
1 file changed, 39 insertions(+), 34 deletions(-)
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index c936272bcd81..026003ba507d 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -2271,6 +2271,44 @@ static int mmc_shutdown(struct mmc_host *host)
return err;
}
+static bool mmc_card_can_reset(struct mmc_card *card)
+{
+ u8 rst_n_function;
+
+ rst_n_function = card->ext_csd.rst_n_function;
+ return ((rst_n_function & EXT_CSD_RST_N_EN_MASK) == EXT_CSD_RST_N_ENABLED);
+}
+
+static int _mmc_hw_reset(struct mmc_host *host)
+{
+ struct mmc_card *card = host->card;
+
+ if ((host->caps & MMC_CAP_HW_RESET) && host->ops->card_hw_reset &&
+ mmc_card_can_reset(card)) {
+ /* If the card accept RST_n signal, send it. */
+ mmc_set_clock(host, host->f_init);
+ host->ops->card_hw_reset(host);
+ /* Set initial state and call mmc_set_ios */
+ mmc_set_initial_state(host);
+ } else {
+ /* Do a brute force power cycle */
+ mmc_power_cycle(host, card->ocr);
+ mmc_pwrseq_reset(host);
+ }
+ return mmc_init_card(host, card->ocr, card);
+}
+
+static int mmc_hw_reset_recovery(struct mmc_host *host)
+{
+ /*
+ * In the case of recovery, we can't expect flushing the cache to work
+ * always, but we have a go and ignore errors.
+ */
+ _mmc_flush_cache(host);
+
+ return _mmc_hw_reset(host);
+}
+
/*
* Callback for resume.
*/
@@ -2319,39 +2357,6 @@ static int mmc_runtime_resume(struct mmc_host *host)
return 0;
}
-static bool mmc_card_can_reset(struct mmc_card *card)
-{
- u8 rst_n_function;
-
- rst_n_function = card->ext_csd.rst_n_function;
- return ((rst_n_function & EXT_CSD_RST_N_EN_MASK) == EXT_CSD_RST_N_ENABLED);
-}
-
-static int _mmc_hw_reset(struct mmc_host *host)
-{
- struct mmc_card *card = host->card;
-
- /*
- * In the case of recovery, we can't expect flushing the cache to work
- * always, but we have a go and ignore errors.
- */
- _mmc_flush_cache(host);
-
- if ((host->caps & MMC_CAP_HW_RESET) && host->ops->card_hw_reset &&
- mmc_card_can_reset(card)) {
- /* If the card accept RST_n signal, send it. */
- mmc_set_clock(host, host->f_init);
- host->ops->card_hw_reset(host);
- /* Set initial state and call mmc_set_ios */
- mmc_set_initial_state(host);
- } else {
- /* Do a brute force power cycle */
- mmc_power_cycle(host, card->ocr);
- mmc_pwrseq_reset(host);
- }
- return mmc_init_card(host, card->ocr, card);
-}
-
/**
* _mmc_handle_undervoltage - Handle an undervoltage event for MMC/eMMC devices
* @host: MMC host structure
@@ -2410,7 +2415,7 @@ static const struct mmc_bus_ops mmc_ops = {
.runtime_resume = mmc_runtime_resume,
.alive = mmc_alive,
.shutdown = mmc_shutdown,
- .hw_reset = _mmc_hw_reset,
+ .hw_reset = mmc_hw_reset_recovery,
.cache_enabled = _mmc_cache_enabled,
.flush_cache = _mmc_flush_cache,
.handle_undervoltage = _mmc_handle_undervoltage,
--
2.34.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v11 6/6] mmc: core: Add support for resetting an eMMC at system resume
2026-10-30 18:10 [PATCH v11 0/6] mmc: core: Keep the card powered across suspend when firmware needs it live Kamal Dasu
` (4 preceding siblings ...)
2026-10-30 18:10 ` [PATCH v11 5/6] mmc: core: Move and split reset functions for eMMC Kamal Dasu
@ 2026-10-30 18:10 ` Kamal Dasu
2026-10-30 18:29 ` sashiko-bot
5 siblings, 1 reply; 8+ messages in thread
From: Kamal Dasu @ 2026-10-30 18:10 UTC (permalink / raw)
To: linux-mmc, Ulf Hansson
Cc: Ulf Hansson, Adrian Hunter, Florian Fainelli, Wolfram Sang,
Oleksij Rempel, linux-kernel, devicetree, Rob Herring,
Conor Dooley, Krzysztof Kozlowski, Krzysztof Kozlowski,
Krzysztof Kozlowski, Shawn Lin
From: Ulf Hansson <ulf.hansson@oss.qualcomm.com>
The DT property reset-card-at-resume specifies that we need to make a reset
of an eMMC card at system resume, assuming it also has stayed powered on
during system suspend.
To implement support for this, let's start by parsing for the new DT
property and set the new bit MMC_CAP2_RESET_AT_RESUME if it's found. Based
on the property, we must also set MMC_PM_KEEP_POWER in the pm_flags for the
host, to keep the eMMC powered on during system suspend.
Finally, to manage the actual reset during system resume, let's extend
mmc_resume() to support the needed behaviour.
The property only makes sense together with keep-power-in-suspend, as the
card would otherwise be powered off and system suspend is refused. Warn
about that while parsing the DT properties, to flag the misconfiguration
upfront. While at it, claim the host around the reset in mmc_resume(), as
it sends commands to the card.
Signed-off-by: Ulf Hansson <ulf.hansson@oss.qualcomm.com>
Co-developed-by: Kamal Dasu <kamal.dasu@broadcom.com>
Signed-off-by: Kamal Dasu <kamal.dasu@broadcom.com>
---
drivers/mmc/core/host.c | 13 +++++++++++++
drivers/mmc/core/mmc.c | 8 ++++++++
include/linux/mmc/host.h | 1 +
3 files changed, 22 insertions(+)
diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
index 8e9e61839198..8b38ff45d20f 100644
--- a/drivers/mmc/core/host.c
+++ b/drivers/mmc/core/host.c
@@ -48,6 +48,14 @@ static int mmc_host_class_prepare(struct device *dev)
if (host->bus_ops->pre_suspend)
return host->bus_ops->pre_suspend(host);
+ /*
+ * If it's required to make a reset of the card at system resume, this
+ * indirectly also means that we must keep the card powered on during
+ * system suspend.
+ */
+ if (host->caps2 & MMC_CAP2_RESET_AT_RESUME)
+ return mmc_set_host_pm_flags(host, MMC_PM_KEEP_POWER);
+
return 0;
}
@@ -375,6 +383,11 @@ int mmc_of_parse(struct mmc_host *host)
host->pm_caps |= MMC_PM_KEEP_POWER;
if (device_property_read_bool(dev, "wakeup-source"))
host->pm_caps |= MMC_PM_WAKE_SDIO_IRQ;
+ if (device_property_read_bool(dev, "reset-card-at-resume")) {
+ host->caps2 |= MMC_CAP2_RESET_AT_RESUME;
+ if (!(host->pm_caps & MMC_PM_KEEP_POWER))
+ dev_warn(dev, "reset-card-at-resume without keep-power-in-suspend, system suspend will fail\n");
+ }
if (device_property_read_bool(dev, "mmc-ddr-3_3v"))
host->caps |= MMC_CAP_3_3V_DDR;
if (device_property_read_bool(dev, "mmc-ddr-1_8v"))
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 026003ba507d..a9e3cf7ae039 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -2320,6 +2320,14 @@ static int mmc_resume(struct mmc_host *host)
}
pm_runtime_enable(&host->card->dev);
+
+ if (mmc_card_keep_power(host) &&
+ host->caps2 & MMC_CAP2_RESET_AT_RESUME) {
+ mmc_claim_host(host);
+ _mmc_hw_reset(host);
+ mmc_release_host(host);
+ }
+
host->pm_flags &= ~MMC_PM_KEEP_POWER;
return 0;
}
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 032c018650e0..3c0ea74e3e35 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -430,6 +430,7 @@ struct mmc_host {
u32 caps2; /* More host capabilities */
#define MMC_CAP2_BOOTPART_NOACC (1 << 0) /* Boot partition no access */
+#define MMC_CAP2_RESET_AT_RESUME BIT(1) /* Reset the card at system resume */
#define MMC_CAP2_FULL_PWR_CYCLE (1 << 2) /* Can do full power cycle */
#define MMC_CAP2_FULL_PWR_CYCLE_IN_SUSPEND (1 << 3) /* Can do full power cycle in suspend */
#define MMC_CAP2_HS200_1_8V_SDR (1 << 5) /* can support */
--
2.34.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH v11 6/6] mmc: core: Add support for resetting an eMMC at system resume
2026-10-30 18:10 ` [PATCH v11 6/6] mmc: core: Add support for resetting an eMMC at system resume Kamal Dasu
@ 2026-10-30 18:29 ` sashiko-bot
0 siblings, 0 replies; 8+ messages in thread
From: sashiko-bot @ 2026-10-30 18:29 UTC (permalink / raw)
To: Kamal Dasu; +Cc: devicetree, robh, conor+dt
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] mmc: core: unchecked _mmc_hw_reset() error and premature active state in mmc_resume()
--
commit f67582c90bab341460117ecbfa06f572b7755129
Author: Ulf Hansson <ulf.hansson@oss.qualcomm.com>
mmc: core: Add support for resetting an eMMC at system resume
This commit adds support for the reset-card-at-resume DT property by setting
MMC_CAP2_RESET_AT_RESUME and MMC_PM_KEEP_POWER, and calling _mmc_hw_reset()
during mmc_resume().
> diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
> index c183afbed30c8..793767c5159f2 100644
> --- a/drivers/mmc/core/mmc.c
> +++ b/drivers/mmc/core/mmc.c
> @@ -2320,6 +2320,14 @@ static int mmc_resume(struct mmc_host *host)
> }
>
> pm_runtime_enable(&host->card->dev);
> +
> + if (mmc_card_keep_power(host) &&
> + host->caps2 & MMC_CAP2_RESET_AT_RESUME) {
> + mmc_claim_host(host);
> + _mmc_hw_reset(host);
> + mmc_release_host(host);
> + }
[Severity: Medium]
Should mmc_resume() check the return value of _mmc_hw_reset(host) and avoid
marking the card active before the reset succeeds?
Right now, when mmc_card_keep_power(host) is true, mmc_resume() unconditionally
marks the card runtime-active and clears the suspended state first:
drivers/mmc/core/mmc.c:mmc_resume() {
if (mmc_card_keep_power(host)) {
pm_runtime_set_active(&host->card->dev);
mmc_card_clr_suspended(host->card);
}
pm_runtime_enable(&host->card->dev);
...
}
After that, _mmc_hw_reset(host) resets or power-cycles the card, resets the
host IOS state to initial values via mmc_set_initial_state(host), and calls
mmc_init_card(host, card->ocr, card).
If mmc_init_card() fails (for example due to a command timeout, voltage or
timing switch failure, or tuning error), mmc_resume() discards the error and
returns 0 to mmc_bus_resume(). That suppresses the resume failure warning in
mmc_bus_resume() and leaves the card marked runtime-active and unsuspended
while the hardware remains in an uninitialized reset state, preventing a
subsequent runtime resume via _mmc_resume() from re-initializing the card.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261030181034.3811225-1-kamal.dasu@broadcom.com?part=6
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2026-10-30 18:29 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-30 18:10 [PATCH v11 0/6] mmc: core: Keep the card powered across suspend when firmware needs it live Kamal Dasu
2026-10-30 18:10 ` [PATCH v11 1/6] dt-bindings: mmc: Extend keep-power-in-suspend beyond SDIO Kamal Dasu
2026-10-30 18:10 ` [PATCH v11 2/6] dt-bindings: mmc: Add reset-card-at-resume property Kamal Dasu
2026-10-30 18:10 ` [PATCH v11 3/6] mmc: core: Add option to keep an eMMC powered on at system suspend Kamal Dasu
2026-10-30 18:10 ` [PATCH v11 4/6] mmc: core: Split sdio_set_host_pm_flags() Kamal Dasu
2026-10-30 18:10 ` [PATCH v11 5/6] mmc: core: Move and split reset functions for eMMC Kamal Dasu
2026-10-30 18:10 ` [PATCH v11 6/6] mmc: core: Add support for resetting an eMMC at system resume Kamal Dasu
2026-10-30 18:29 ` sashiko-bot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox