From: Wolfram Sang <wsa+renesas@sang-engineering.com>
To: linux-renesas-soc@vger.kernel.org
Cc: Wolfram Sang <wsa+renesas@sang-engineering.com>,
Ulf Hansson <ulf.hansson@linaro.org>,
linux-mmc@vger.kernel.org
Subject: [RFC PATCH v2] mmc: suspend MMC also when unbinding
Date: Mon, 4 Nov 2024 11:18:42 +0200 [thread overview]
Message-ID: <20241104092215.20946-2-wsa+renesas@sang-engineering.com> (raw)
When unbinding a MMC host, the card should be suspended. Otherwise,
problems may arise. E.g. the card still expects power-off notifications
but there is no host to send them anymore. Shimoda-san tried disabling
notifications only, but there were issues with his approaches [1] [2].
Here is my take on it, based on the review comments:
a) 'In principle we would like to run the similar operations at "remove"
as during "system suspend"' [1]
b) 'We want to support a graceful power off sequence or the card...' [2]
So, first, mmc_remove_card() gets improved to mark the card as "not
present" and to call the bus specific suspend() handler.
Then, _mmc_suspend gets extended to recognize another reason of being
called, namely when a card removal happens. Building upon the now
updated mmc_remove_card(), this is the case when the card is flagged as
"not present".
The logic of either sending a notification or sending the card to sleep
gets updated to handle this new reason. Controllers able to do full
power cycles will still do a full power cycle. Controllers which can
only do power cycles in suspend, will send the card to sleep.
All this is for MMC. SD/SDIO are unaffected because they are not using
the 'card present' flag.
Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
[1] https://patchwork.kernel.org/project/linux-renesas-soc/patch/1602581312-23607-1-git-send-email-yoshihiro.shimoda.uh@renesas.com/
[2] https://patchwork.kernel.org/project/linux-mmc/patch/1605005330-7178-1-git-send-email-yoshihiro.shimoda.uh@renesas.com/
---
Lightly tested with a Renesas R-Car S4 Spider board. It bascially works
as expected. Serious testing postponed until the generic direction of
this is approved :)
drivers/mmc/core/bus.c | 3 +++
drivers/mmc/core/mmc.c | 29 +++++++++++++++++++++--------
2 files changed, 24 insertions(+), 8 deletions(-)
diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c
index 0ddaee0eae54..52704d39c6d5 100644
--- a/drivers/mmc/core/bus.c
+++ b/drivers/mmc/core/bus.c
@@ -403,5 +403,8 @@ void mmc_remove_card(struct mmc_card *card)
host->cqe_enabled = false;
}
+ card->state &= ~MMC_STATE_PRESENT; // TBD: mmc_card_clear_present()
+ host->bus_ops->suspend(host);
+
put_device(&card->dev);
}
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 6a23be214543..2bcf9ee0caa8 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -32,6 +32,12 @@
#define MIN_CACHE_EN_TIMEOUT_MS 1600
#define CACHE_FLUSH_TIMEOUT_MS 30000 /* 30s */
+enum mmc_pm_reason {
+ MMC_PM_REASON_SHUTDOWN,
+ MMC_PM_REASON_SUSPEND,
+ MMC_PM_REASON_REMOVAL,
+};
+
static const unsigned int tran_exp[] = {
10000, 100000, 1000000, 10000000,
0, 0, 0, 0
@@ -2104,11 +2110,16 @@ static int _mmc_flush_cache(struct mmc_host *host)
return err;
}
-static int _mmc_suspend(struct mmc_host *host, bool is_suspend)
+static int _mmc_suspend(struct mmc_host *host, enum mmc_pm_reason reason)
{
int err = 0;
- unsigned int notify_type = is_suspend ? EXT_CSD_POWER_OFF_SHORT :
- EXT_CSD_POWER_OFF_LONG;
+ unsigned int notify_type = reason == MMC_PM_REASON_SUSPEND ?
+ EXT_CSD_POWER_OFF_SHORT : EXT_CSD_POWER_OFF_LONG;
+ bool can_pwr_cycle_now = (host->caps2 & MMC_CAP2_FULL_PWR_CYCLE) ||
+ ((host->caps2 & MMC_CAP2_FULL_PWR_CYCLE_IN_SUSPEND) &&
+ reason == MMC_PM_REASON_SUSPEND);
+
+ pr_info("%s: suspend reason %d, can pwr cycle %d\n", mmc_hostname(host), reason, can_pwr_cycle_now);
mmc_claim_host(host);
@@ -2119,9 +2130,9 @@ static int _mmc_suspend(struct mmc_host *host, bool is_suspend)
if (err)
goto out;
+ /* Notify if pwr_cycle is possible or power gets cut because of shutdown */
if (mmc_can_poweroff_notify(host->card) &&
- ((host->caps2 & MMC_CAP2_FULL_PWR_CYCLE) || !is_suspend ||
- (host->caps2 & MMC_CAP2_FULL_PWR_CYCLE_IN_SUSPEND)))
+ (can_pwr_cycle_now || reason == MMC_PM_REASON_SHUTDOWN))
err = mmc_poweroff_notify(host->card, notify_type);
else if (mmc_can_sleep(host->card))
err = mmc_sleep(host);
@@ -2142,9 +2153,11 @@ static int _mmc_suspend(struct mmc_host *host, bool is_suspend)
*/
static int mmc_suspend(struct mmc_host *host)
{
+ enum mmc_pm_reason reason = mmc_card_present(host->card) ?
+ MMC_PM_REASON_SUSPEND : MMC_PM_REASON_REMOVAL;
int err;
- err = _mmc_suspend(host, true);
+ err = _mmc_suspend(host, reason);
if (!err) {
pm_runtime_disable(&host->card->dev);
pm_runtime_set_suspended(&host->card->dev);
@@ -2191,7 +2204,7 @@ static int mmc_shutdown(struct mmc_host *host)
err = _mmc_resume(host);
if (!err)
- err = _mmc_suspend(host, false);
+ err = _mmc_suspend(host, MMC_PM_REASON_SHUTDOWN);
return err;
}
@@ -2215,7 +2228,7 @@ static int mmc_runtime_suspend(struct mmc_host *host)
if (!(host->caps & MMC_CAP_AGGRESSIVE_PM))
return 0;
- err = _mmc_suspend(host, true);
+ err = _mmc_suspend(host, MMC_PM_REASON_SUSPEND);
if (err)
pr_err("%s: error %d doing aggressive suspend\n",
mmc_hostname(host), err);
--
2.45.2
next reply other threads:[~2024-11-04 9:22 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-11-04 9:18 Wolfram Sang [this message]
2024-12-06 11:15 ` [RFC PATCH v2] mmc: suspend MMC also when unbinding Wolfram Sang
2024-12-10 16:03 ` Ulf Hansson
2025-01-22 9:28 ` Wolfram Sang
2025-03-14 9:27 ` Wolfram Sang
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20241104092215.20946-2-wsa+renesas@sang-engineering.com \
--to=wsa+renesas@sang-engineering.com \
--cc=linux-mmc@vger.kernel.org \
--cc=linux-renesas-soc@vger.kernel.org \
--cc=ulf.hansson@linaro.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox