summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Norris <briannorris@chromium.org>2022-09-13 18:40:10 -0700
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2022-10-12 09:53:28 +0200
commitf6f740f6ca3b0f49608334588bb657e620ab5604 (patch)
tree89636a0dff71dc7a9f6de69893dc3bdb69351f59
parent9635e05e015a6762a6dfa6e59d64080e9773e1a6 (diff)
mmc: core: Terminate infinite loop in SD-UHS voltage switch
[ Upstream commit e9233917a7e53980664efbc565888163c0a33c3f ] This loop intends to retry a max of 10 times, with some implicit termination based on the SD_{R,}OCR_S18A bit. Unfortunately, the termination condition depends on the value reported by the SD card (*rocr), which may or may not correctly reflect what we asked it to do. Needless to say, it's not wise to rely on the card doing what we expect; we should at least terminate the loop regardless. So, check both the input and output values, so we ensure we will terminate regardless of the SD card behavior. Note that SDIO learned a similar retry loop in commit 0797e5f1453b ("mmc: core: Fixup signal voltage switch"), but that used the 'ocr' result, and so the current pre-terminating condition looks like: rocr & ocr & R4_18V_PRESENT (i.e., it doesn't have the same bug.) This addresses a number of crash reports seen on ChromeOS that look like the following: ... // lots of repeated: ... <4>[13142.846061] mmc1: Skipping voltage switch <4>[13143.406087] mmc1: Skipping voltage switch <4>[13143.964724] mmc1: Skipping voltage switch <4>[13144.526089] mmc1: Skipping voltage switch <4>[13145.086088] mmc1: Skipping voltage switch <4>[13145.645941] mmc1: Skipping voltage switch <3>[13146.153969] INFO: task halt:30352 blocked for more than 122 seconds. ... Fixes: f2119df6b764 ("mmc: sd: add support for signal voltage switch procedure") Cc: <stable@vger.kernel.org> Signed-off-by: Brian Norris <briannorris@chromium.org> Reviewed-by: Guenter Roeck <linux@roeck-us.net> Link: https://lore.kernel.org/r/20220914014010.2076169-1-briannorris@chromium.org Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
-rw-r--r--drivers/mmc/core/sd.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index eaa2679b9466..86a8a1f56583 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -863,7 +863,8 @@ try_again:
* the CCS bit is set as well. We deliberately deviate from the spec in
* regards to this, which allows UHS-I to be supported for SDSC cards.
*/
- if (!mmc_host_is_spi(host) && rocr && (*rocr & SD_ROCR_S18A)) {
+ if (!mmc_host_is_spi(host) && (ocr & SD_OCR_S18R) &&
+ rocr && (*rocr & SD_ROCR_S18A)) {
err = mmc_set_uhs_voltage(host, pocr);
if (err == -EAGAIN) {
retries--;