]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - queue-4.19/mmc-sdhci-handle-auto-command-errors.patch
Linux 4.14.114
[thirdparty/kernel/stable-queue.git] / queue-4.19 / mmc-sdhci-handle-auto-command-errors.patch
1 From 413bdc69fdc13745967d82cfe3bb59a03949b522 Mon Sep 17 00:00:00 2001
2 From: Adrian Hunter <adrian.hunter@intel.com>
3 Date: Thu, 15 Nov 2018 15:53:43 +0200
4 Subject: mmc: sdhci: Handle auto-command errors
5
6 [ Upstream commit af849c86109d79222e549826068bbf4e7f9a2472 ]
7
8 If the host controller supports auto-commands then enable the auto-command
9 error interrupt and handle it. In the case of auto-CMD23, the error is
10 treated the same as manual CMD23 error. In the case of auto-CMD12,
11 commands-during-transfer are not permitted, so the error handling is
12 treated the same as a data error.
13
14 Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
15 Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
16 Signed-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
22 diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
23 index 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 }
82 diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
83 index 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 --
108 2.19.1
109