]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/4.14.130/mmc-core-prevent-processing-sdio-irqs-when-the-card-is-suspended.patch
Linux 4.14.130
[thirdparty/kernel/stable-queue.git] / releases / 4.14.130 / mmc-core-prevent-processing-sdio-irqs-when-the-card-is-suspended.patch
CommitLineData
1aebfeb4
GKH
1From 83293386bc95cf5e9f0c0175794455835bd1cb4a Mon Sep 17 00:00:00 2001
2From: Ulf Hansson <ulf.hansson@linaro.org>
3Date: Tue, 18 Jun 2019 14:05:17 +0200
4Subject: mmc: core: Prevent processing SDIO IRQs when the card is suspended
5
6From: Ulf Hansson <ulf.hansson@linaro.org>
7
8commit 83293386bc95cf5e9f0c0175794455835bd1cb4a upstream.
9
10Processing of SDIO IRQs must obviously be prevented while the card is
11system suspended, otherwise we may end up trying to communicate with an
12uninitialized SDIO card.
13
14Reports throughout the years shows that this is not only a theoretical
15problem, but a real issue. So, let's finally fix this problem, by keeping
16track of the state for the card and bail out before processing the SDIO
17IRQ, in case the card is suspended.
18
19Cc: stable@vger.kernel.org
20Reported-by: Douglas Anderson <dianders@chromium.org>
21Tested-by: Douglas Anderson <dianders@chromium.org>
22Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
23Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
24
25---
26 drivers/mmc/core/sdio.c | 13 ++++++++++++-
27 drivers/mmc/core/sdio_irq.c | 4 ++++
28 2 files changed, 16 insertions(+), 1 deletion(-)
29
30--- a/drivers/mmc/core/sdio.c
31+++ b/drivers/mmc/core/sdio.c
32@@ -907,6 +907,10 @@ static int mmc_sdio_pre_suspend(struct m
33 */
34 static int mmc_sdio_suspend(struct mmc_host *host)
35 {
36+ /* Prevent processing of SDIO IRQs in suspended state. */
37+ mmc_card_set_suspended(host->card);
38+ cancel_delayed_work_sync(&host->sdio_irq_work);
39+
40 mmc_claim_host(host);
41
42 if (mmc_card_keep_power(host) && mmc_card_wake_sdio_irq(host))
43@@ -962,13 +966,20 @@ static int mmc_sdio_resume(struct mmc_ho
44 err = sdio_enable_4bit_bus(host->card);
45 }
46
47- if (!err && host->sdio_irqs) {
48+ if (err)
49+ goto out;
50+
51+ /* Allow SDIO IRQs to be processed again. */
52+ mmc_card_clr_suspended(host->card);
53+
54+ if (host->sdio_irqs) {
55 if (!(host->caps2 & MMC_CAP2_SDIO_IRQ_NOTHREAD))
56 wake_up_process(host->sdio_irq_thread);
57 else if (host->caps & MMC_CAP_SDIO_IRQ)
58 host->ops->enable_sdio_irq(host, 1);
59 }
60
61+out:
62 mmc_release_host(host);
63
64 host->pm_flags &= ~MMC_PM_KEEP_POWER;
65--- a/drivers/mmc/core/sdio_irq.c
66+++ b/drivers/mmc/core/sdio_irq.c
67@@ -38,6 +38,10 @@ static int process_sdio_pending_irqs(str
68 unsigned char pending;
69 struct sdio_func *func;
70
71+ /* Don't process SDIO IRQs if the card is suspended. */
72+ if (mmc_card_suspended(card))
73+ return 0;
74+
75 /*
76 * Optimization, if there is only 1 function interrupt registered
77 * and we know an IRQ was signaled then call irq handler directly.