| From d587c60ea833a0440f23bcade5c064b29c15e91f Mon Sep 17 00:00:00 2001 |
| From: Ulf Hansson <ulf.hansson@linaro.org> |
| Date: Tue, 24 Mar 2020 19:07:34 +0100 |
| Subject: [PATCH] mmc: core: Allow host controllers to require R1B for CMD6 |
| |
| [ Upstream commit 1292e3efb149ee21d8d33d725eeed4e6b1ade963 ] |
| |
| It has turned out that some host controllers can't use R1B for CMD6 and |
| other commands that have R1B associated with them. Therefore invent a new |
| host cap, MMC_CAP_NEED_RSP_BUSY to let them specify this. |
| |
| In __mmc_switch(), let's check the flag and use it to prevent R1B responses |
| from being converted into R1. Note that, this also means that the host are |
| on its own, when it comes to manage the busy timeout. |
| |
| Suggested-by: Sowjanya Komatineni <skomatineni@nvidia.com> |
| Cc: <stable@vger.kernel.org> |
| Tested-by: Anders Roxell <anders.roxell@linaro.org> |
| Tested-by: Sowjanya Komatineni <skomatineni@nvidia.com> |
| Tested-by: Faiz Abbas <faiz_abbas@ti.com> |
| Tested-By: Peter Geis <pgwipeout@gmail.com> |
| Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| [PG: use v5.4-stable version instead of mainline.] |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c |
| index 09113b9ad679..18a7afb2a5b2 100644 |
| --- a/drivers/mmc/core/mmc_ops.c |
| +++ b/drivers/mmc/core/mmc_ops.c |
| @@ -538,10 +538,12 @@ int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value, |
| * If the cmd timeout and the max_busy_timeout of the host are both |
| * specified, let's validate them. A failure means we need to prevent |
| * the host from doing hw busy detection, which is done by converting |
| - * to a R1 response instead of a R1B. |
| + * to a R1 response instead of a R1B. Note, some hosts requires R1B, |
| + * which also means they are on their own when it comes to deal with the |
| + * busy timeout. |
| */ |
| - if (timeout_ms && host->max_busy_timeout && |
| - (timeout_ms > host->max_busy_timeout)) |
| + if (!(host->caps & MMC_CAP_NEED_RSP_BUSY) && timeout_ms && |
| + host->max_busy_timeout && (timeout_ms > host->max_busy_timeout)) |
| use_r1b_resp = false; |
| |
| cmd.opcode = MMC_SWITCH; |
| diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h |
| index 56a8ad506072..4a4a64834d8e 100644 |
| --- a/include/linux/mmc/host.h |
| +++ b/include/linux/mmc/host.h |
| @@ -332,6 +332,7 @@ struct mmc_host { |
| MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104 | \ |
| MMC_CAP_UHS_DDR50) |
| #define MMC_CAP_SYNC_RUNTIME_PM (1 << 21) /* Synced runtime PM suspends. */ |
| +#define MMC_CAP_NEED_RSP_BUSY (1 << 22) /* Commands with R1B can't use R1. */ |
| #define MMC_CAP_DRIVER_TYPE_A (1 << 23) /* Host supports Driver Type A */ |
| #define MMC_CAP_DRIVER_TYPE_C (1 << 24) /* Host supports Driver Type C */ |
| #define MMC_CAP_DRIVER_TYPE_D (1 << 25) /* Host supports Driver Type D */ |
| -- |
| 2.27.0 |
| |