]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/4.19.37/mmc-sdhci-handle-auto-command-errors.patch
Linux 4.19.37
[thirdparty/kernel/stable-queue.git] / releases / 4.19.37 / mmc-sdhci-handle-auto-command-errors.patch
CommitLineData
b3fe817e
SL
1From 413bdc69fdc13745967d82cfe3bb59a03949b522 Mon Sep 17 00:00:00 2001
2From: Adrian Hunter <adrian.hunter@intel.com>
3Date: Thu, 15 Nov 2018 15:53:43 +0200
4Subject: mmc: sdhci: Handle auto-command errors
5
6[ Upstream commit af849c86109d79222e549826068bbf4e7f9a2472 ]
7
8If the host controller supports auto-commands then enable the auto-command
9error interrupt and handle it. In the case of auto-CMD23, the error is
10treated the same as manual CMD23 error. In the case of auto-CMD12,
11commands-during-transfer are not permitted, so the error handling is
12treated the same as a data error.
13
14Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
15Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
16Signed-off-by: Sasha Levin <sashal@kernel.org>
17---
18 drivers/mmc/host/sdhci.c | 35 +++++++++++++++++++++++++++++++++++
19 drivers/mmc/host/sdhci.h | 7 ++++++-
20 2 files changed, 41 insertions(+), 1 deletion(-)
21
22diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
23index 0eb05a42a857..c749d3dc1d36 100644
24--- a/drivers/mmc/host/sdhci.c
25+++ b/drivers/mmc/host/sdhci.c
26@@ -841,6 +841,11 @@ static void sdhci_set_transfer_irqs(struct sdhci_host *host)
27 else
28 host->ier = (host->ier & ~dma_irqs) | pio_irqs;
29
30+ if (host->flags & (SDHCI_AUTO_CMD23 | SDHCI_AUTO_CMD12))
31+ host->ier |= SDHCI_INT_AUTO_CMD_ERR;
32+ else
33+ host->ier &= ~SDHCI_INT_AUTO_CMD_ERR;
34+
35 sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
36 sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
37 }
38@@ -2642,6 +2647,21 @@ static void sdhci_timeout_data_timer(struct timer_list *t)
39
40 static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask, u32 *intmask_p)
41 {
42+ /* Handle auto-CMD12 error */
43+ if (intmask & SDHCI_INT_AUTO_CMD_ERR && host->data_cmd) {
44+ struct mmc_request *mrq = host->data_cmd->mrq;
45+ u16 auto_cmd_status = sdhci_readw(host, SDHCI_AUTO_CMD_STATUS);
46+ int data_err_bit = (auto_cmd_status & SDHCI_AUTO_CMD_TIMEOUT) ?
47+ SDHCI_INT_DATA_TIMEOUT :
48+ SDHCI_INT_DATA_CRC;
49+
50+ /* Treat auto-CMD12 error the same as data error */
51+ if (!mrq->sbc && (host->flags & SDHCI_AUTO_CMD12)) {
52+ *intmask_p |= data_err_bit;
53+ return;
54+ }
55+ }
56+
57 if (!host->cmd) {
58 /*
59 * SDHCI recovers from errors by resetting the cmd and data
60@@ -2676,6 +2696,21 @@ static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask, u32 *intmask_p)
61 return;
62 }
63
64+ /* Handle auto-CMD23 error */
65+ if (intmask & SDHCI_INT_AUTO_CMD_ERR) {
66+ struct mmc_request *mrq = host->cmd->mrq;
67+ u16 auto_cmd_status = sdhci_readw(host, SDHCI_AUTO_CMD_STATUS);
68+ int err = (auto_cmd_status & SDHCI_AUTO_CMD_TIMEOUT) ?
69+ -ETIMEDOUT :
70+ -EILSEQ;
71+
72+ if (mrq->sbc && (host->flags & SDHCI_AUTO_CMD23)) {
73+ mrq->sbc->error = err;
74+ sdhci_finish_mrq(host, mrq);
75+ return;
76+ }
77+ }
78+
79 if (intmask & SDHCI_INT_RESPONSE)
80 sdhci_finish_command(host);
81 }
82diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
83index 33a7728c71fa..0f8c4f3ccafc 100644
84--- a/drivers/mmc/host/sdhci.h
85+++ b/drivers/mmc/host/sdhci.h
86@@ -151,7 +151,8 @@
87 #define SDHCI_INT_ERROR_MASK 0xFFFF8000
88
89 #define SDHCI_INT_CMD_MASK (SDHCI_INT_RESPONSE | SDHCI_INT_TIMEOUT | \
90- SDHCI_INT_CRC | SDHCI_INT_END_BIT | SDHCI_INT_INDEX)
91+ SDHCI_INT_CRC | SDHCI_INT_END_BIT | SDHCI_INT_INDEX | \
92+ SDHCI_INT_AUTO_CMD_ERR)
93 #define SDHCI_INT_DATA_MASK (SDHCI_INT_DATA_END | SDHCI_INT_DMA_END | \
94 SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL | \
95 SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_DATA_CRC | \
96@@ -167,6 +168,10 @@
97 #define SDHCI_CQE_INT_MASK (SDHCI_CQE_INT_ERR_MASK | SDHCI_INT_CQE)
98
99 #define SDHCI_AUTO_CMD_STATUS 0x3C
100+#define SDHCI_AUTO_CMD_TIMEOUT 0x00000002
101+#define SDHCI_AUTO_CMD_CRC 0x00000004
102+#define SDHCI_AUTO_CMD_END_BIT 0x00000008
103+#define SDHCI_AUTO_CMD_INDEX 0x00000010
104
105 #define SDHCI_HOST_CONTROL2 0x3E
106 #define SDHCI_CTRL_UHS_MASK 0x0007
107--
1082.19.1
109