--- zzzz-none-000/linux-5.15.111/drivers/mmc/core/core.c 2023-05-11 14:00:40.000000000 +0000 +++ puma7-atom-6670-761/linux-5.15.111/drivers/mmc/core/core.c 2024-02-07 10:23:07.000000000 +0000 @@ -47,6 +47,11 @@ #include "sd_ops.h" #include "sdio_ops.h" +#ifdef CONFIG_HW_MUTEXES +#include +#include "../host/sdhci.h" +#endif + /* The max erase timeout, used when host->max_busy_timeout isn't specified */ #define MMC_ERASE_TIMEOUT_MS (60 * 1000) /* 60 s */ #define SD_DISCARD_TIMEOUT_MS (250) @@ -410,7 +415,7 @@ mmc_retune_recheck(host); - pr_debug("%s: req failed (CMD%u): %d, retrying...\n", + pr_info("%s: req failed (CMD%u): %d, retrying...\n", mmc_hostname(host), cmd->opcode, cmd->error); cmd->retries--; cmd->error = 0; @@ -785,6 +790,7 @@ unsigned long flags; int stop; bool pm = false; + bool hw_lock __maybe_unused = false; might_sleep(); @@ -804,13 +810,20 @@ host->claimed = 1; mmc_ctx_set_claimer(host, ctx, task); host->claim_cnt += 1; - if (host->claim_cnt == 1) + if (host->claim_cnt == 1) { + hw_lock = true; pm = true; + } } else wake_up(&host->wq); spin_unlock_irqrestore(&host->lock, flags); remove_wait_queue(&host->wq, &wait); +#if IS_ENABLED(CONFIG_HW_MUTEXES) + if (hw_lock) + MMC_LOCK_HW_MUTEX(host); +#endif + if (pm) pm_runtime_get_sync(mmc_dev(host)); @@ -840,6 +853,10 @@ host->claimer->task = NULL; host->claimer = NULL; spin_unlock_irqrestore(&host->lock, flags); + +#ifdef CONFIG_HW_MUTEXES + MMC_UNLOCK_HW_MUTEX(host); +#endif wake_up(&host->wq); pm_runtime_mark_last_busy(mmc_dev(host)); if (host->caps & MMC_CAP_SYNC_RUNTIME_PM) @@ -1253,7 +1270,7 @@ power_cycle: if (err) { - pr_debug("%s: Signal voltage switch failed, " + pr_info("%s: Signal voltage switch failed, " "power cycling card\n", mmc_hostname(host)); mmc_power_cycle(host, ocr); } @@ -2241,6 +2258,18 @@ goto out; } +#ifdef CONFIG_HW_MUTEXES + if (MMC_HOST_SUPPORTS_HW_MUTEX(host)) + { + // We disabled register writes during initialization and the host is not + // currently initialized. Power up then power cycle the emmc/host to + // ensure it is configured as it believes it is currently off and during + // the cycle, the off is ignored when it shouldn't be. + mmc_power_up(host, host->ocr_avail); + mmc_power_cycle(host, host->ocr_avail); + } +#endif + for (i = 0; i < ARRAY_SIZE(freqs); i++) { unsigned int freq = freqs[i]; if (freq > host->f_max) { @@ -2253,6 +2282,7 @@ if (freqs[i] <= host->f_min) break; } + mmc_release_host(host); out: