aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlf Hansson <ulf.hansson@linaro.org>2025-04-07 17:27:55 +0200
committerUlf Hansson <ulf.hansson@linaro.org>2025-05-14 16:59:16 +0200
commitdfc29a10c43d3f2aec853c9bf8b0d9e8f0251a2f (patch)
tree2b38e21807122855d3a53bea373da70c0cd9dd2a
parentmmc: core: Add support for graceful host removal for eMMC (diff)
downloadlinux-dfc29a10c43d3f2aec853c9bf8b0d9e8f0251a2f.tar.gz
linux-dfc29a10c43d3f2aec853c9bf8b0d9e8f0251a2f.zip
mmc: core: Add support for graceful host removal for SD
An mmc host driver may allow to unbind from its corresponding host device. If an SD card is attached to the host, the mmc core will just try to cut the power for it, without obeying to the SD spec that potentially may damage the card. Let's fix this problem by implementing a graceful power-down of the card at host removal. Reviewed-by: Wolfram Sang <wsa+renesas@sang-engineering.com> Tested-by: Wolfram Sang <wsa+renesas@sang-engineering.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> Link: https://lore.kernel.org/r/20250407152759.25160-6-ulf.hansson@linaro.org
-rw-r--r--drivers/mmc/core/sd.c25
1 files changed, 15 insertions, 10 deletions
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index 6847b3fe8887..08ab076fe2f9 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -1613,15 +1613,6 @@ free_card:
}
/*
- * Host is being removed. Free up the current card.
- */
-static void mmc_sd_remove(struct mmc_host *host)
-{
- mmc_remove_card(host->card);
- host->card = NULL;
-}
-
-/*
* Card detection - card is alive.
*/
static int mmc_sd_alive(struct mmc_host *host)
@@ -1646,7 +1637,8 @@ static void mmc_sd_detect(struct mmc_host *host)
mmc_put_card(host->card, NULL);
if (err) {
- mmc_sd_remove(host);
+ mmc_remove_card(host->card);
+ host->card = NULL;
mmc_claim_host(host);
mmc_detach_bus(host);
@@ -1747,6 +1739,19 @@ out:
}
/*
+ * Host is being removed. Free up the current card and do a graceful power-off.
+ */
+static void mmc_sd_remove(struct mmc_host *host)
+{
+ get_device(&host->card->dev);
+ mmc_remove_card(host->card);
+
+ _mmc_sd_suspend(host);
+
+ put_device(&host->card->dev);
+ host->card = NULL;
+}
+/*
* Callback for suspend
*/
static int mmc_sd_suspend(struct mmc_host *host)