|
Takashi Iwai |
1dd236 |
From 66c915d09b942fb3b2b0cb2f56562180901fba17 Mon Sep 17 00:00:00 2001
|
|
Takashi Iwai |
1dd236 |
From: Ulf Hansson <ulf.hansson@linaro.org>
|
|
Takashi Iwai |
1dd236 |
Date: Fri, 3 Dec 2021 15:15:54 +0100
|
|
Takashi Iwai |
1dd236 |
Subject: [PATCH] mmc: core: Disable card detect during shutdown
|
|
Takashi Iwai |
1dd236 |
Git-commit: 66c915d09b942fb3b2b0cb2f56562180901fba17
|
|
Takashi Iwai |
1dd236 |
Patch-mainline: v5.16-rc7
|
|
Takashi Iwai |
1dd236 |
References: git-fixes
|
|
Takashi Iwai |
1dd236 |
|
|
Takashi Iwai |
1dd236 |
It's seems prone to problems by allowing card detect and its corresponding
|
|
Takashi Iwai |
1dd236 |
mmc_rescan() work to run, during platform shutdown. For example, we may end
|
|
Takashi Iwai |
1dd236 |
up turning off the power while initializing a card, which potentially could
|
|
Takashi Iwai |
1dd236 |
damage it.
|
|
Takashi Iwai |
1dd236 |
|
|
Takashi Iwai |
1dd236 |
To avoid this scenario, let's add ->shutdown_pre() callback for the mmc host
|
|
Takashi Iwai |
1dd236 |
class device and then turn of the card detect from there.
|
|
Takashi Iwai |
1dd236 |
|
|
Takashi Iwai |
1dd236 |
Reported-by: Al Cooper <alcooperx@gmail.com>
|
|
Takashi Iwai |
1dd236 |
Suggested-by: Adrian Hunter <adrian.hunter@intel.com>
|
|
Takashi Iwai |
1dd236 |
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
|
|
Takashi Iwai |
1dd236 |
Cc: stable@vger.kernel.org
|
|
Takashi Iwai |
1dd236 |
Link: https://lore.kernel.org/r/20211203141555.105351-1-ulf.hansson@linaro.org
|
|
Takashi Iwai |
1dd236 |
Acked-by: Takashi Iwai <tiwai@suse.de>
|
|
Takashi Iwai |
1dd236 |
|
|
Takashi Iwai |
1dd236 |
---
|
|
Takashi Iwai |
1dd236 |
drivers/mmc/core/core.c | 7 ++++++-
|
|
Takashi Iwai |
1dd236 |
drivers/mmc/core/core.h | 1 +
|
|
Takashi Iwai |
1dd236 |
drivers/mmc/core/host.c | 9 +++++++++
|
|
Takashi Iwai |
1dd236 |
3 files changed, 16 insertions(+), 1 deletion(-)
|
|
Takashi Iwai |
1dd236 |
|
|
Takashi Iwai |
1dd236 |
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
|
|
Takashi Iwai |
1dd236 |
index 240c5af793dc..368f10405e13 100644
|
|
Takashi Iwai |
1dd236 |
--- a/drivers/mmc/core/core.c
|
|
Takashi Iwai |
1dd236 |
+++ b/drivers/mmc/core/core.c
|
|
Takashi Iwai |
1dd236 |
@@ -2264,7 +2264,7 @@ void mmc_start_host(struct mmc_host *host)
|
|
Takashi Iwai |
1dd236 |
_mmc_detect_change(host, 0, false);
|
|
Takashi Iwai |
1dd236 |
}
|
|
Takashi Iwai |
1dd236 |
|
|
Takashi Iwai |
1dd236 |
-void mmc_stop_host(struct mmc_host *host)
|
|
Takashi Iwai |
1dd236 |
+void __mmc_stop_host(struct mmc_host *host)
|
|
Takashi Iwai |
1dd236 |
{
|
|
Takashi Iwai |
1dd236 |
if (host->slot.cd_irq >= 0) {
|
|
Takashi Iwai |
1dd236 |
mmc_gpio_set_cd_wake(host, false);
|
|
Takashi Iwai |
1dd236 |
@@ -2273,6 +2273,11 @@ void mmc_stop_host(struct mmc_host *host)
|
|
Takashi Iwai |
1dd236 |
|
|
Takashi Iwai |
1dd236 |
host->rescan_disable = 1;
|
|
Takashi Iwai |
1dd236 |
cancel_delayed_work_sync(&host->detect);
|
|
Takashi Iwai |
1dd236 |
+}
|
|
Takashi Iwai |
1dd236 |
+
|
|
Takashi Iwai |
1dd236 |
+void mmc_stop_host(struct mmc_host *host)
|
|
Takashi Iwai |
1dd236 |
+{
|
|
Takashi Iwai |
1dd236 |
+ __mmc_stop_host(host);
|
|
Takashi Iwai |
1dd236 |
|
|
Takashi Iwai |
1dd236 |
/* clear pm flags now and let card drivers set them as needed */
|
|
Takashi Iwai |
1dd236 |
host->pm_flags = 0;
|
|
Takashi Iwai |
1dd236 |
diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h
|
|
Takashi Iwai |
1dd236 |
index 7931a4f0137d..f5f3f623ea49 100644
|
|
Takashi Iwai |
1dd236 |
--- a/drivers/mmc/core/core.h
|
|
Takashi Iwai |
1dd236 |
+++ b/drivers/mmc/core/core.h
|
|
Takashi Iwai |
1dd236 |
@@ -70,6 +70,7 @@ static inline void mmc_delay(unsigned int ms)
|
|
Takashi Iwai |
1dd236 |
|
|
Takashi Iwai |
1dd236 |
void mmc_rescan(struct work_struct *work);
|
|
Takashi Iwai |
1dd236 |
void mmc_start_host(struct mmc_host *host);
|
|
Takashi Iwai |
1dd236 |
+void __mmc_stop_host(struct mmc_host *host);
|
|
Takashi Iwai |
1dd236 |
void mmc_stop_host(struct mmc_host *host);
|
|
Takashi Iwai |
1dd236 |
|
|
Takashi Iwai |
1dd236 |
void _mmc_detect_change(struct mmc_host *host, unsigned long delay,
|
|
Takashi Iwai |
1dd236 |
diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
|
|
Takashi Iwai |
1dd236 |
index d4683b1d263f..cf140f4ec864 100644
|
|
Takashi Iwai |
1dd236 |
--- a/drivers/mmc/core/host.c
|
|
Takashi Iwai |
1dd236 |
+++ b/drivers/mmc/core/host.c
|
|
Takashi Iwai |
1dd236 |
@@ -80,9 +80,18 @@ static void mmc_host_classdev_release(struct device *dev)
|
|
Takashi Iwai |
1dd236 |
kfree(host);
|
|
Takashi Iwai |
1dd236 |
}
|
|
Takashi Iwai |
1dd236 |
|
|
Takashi Iwai |
1dd236 |
+static int mmc_host_classdev_shutdown(struct device *dev)
|
|
Takashi Iwai |
1dd236 |
+{
|
|
Takashi Iwai |
1dd236 |
+ struct mmc_host *host = cls_dev_to_mmc_host(dev);
|
|
Takashi Iwai |
1dd236 |
+
|
|
Takashi Iwai |
1dd236 |
+ __mmc_stop_host(host);
|
|
Takashi Iwai |
1dd236 |
+ return 0;
|
|
Takashi Iwai |
1dd236 |
+}
|
|
Takashi Iwai |
1dd236 |
+
|
|
Takashi Iwai |
1dd236 |
static struct class mmc_host_class = {
|
|
Takashi Iwai |
1dd236 |
.name = "mmc_host",
|
|
Takashi Iwai |
1dd236 |
.dev_release = mmc_host_classdev_release,
|
|
Takashi Iwai |
1dd236 |
+ .shutdown_pre = mmc_host_classdev_shutdown,
|
|
Takashi Iwai |
1dd236 |
.pm = MMC_HOST_CLASS_DEV_PM_OPS,
|
|
Takashi Iwai |
1dd236 |
};
|
|
Takashi Iwai |
1dd236 |
|
|
Takashi Iwai |
1dd236 |
--
|
|
Takashi Iwai |
1dd236 |
2.31.1
|
|
Takashi Iwai |
1dd236 |
|