--- zzzz-none-000/linux-4.9.279/drivers/mmc/core/core.c 2021-08-08 06:38:54.000000000 +0000 +++ puma7-arm-6591-750/linux-4.9.279/drivers/mmc/core/core.c 2023-02-08 10:58:13.000000000 +0000 @@ -10,6 +10,14 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ + + /****************************************************************** + + Includes Intel Corporation's changes/modifications dated: 05/2012. + Changed/modified portions - Copyright(c) 2012-2017, Intel Corporation. + +******************************************************************/ + #include #include #include @@ -48,6 +56,9 @@ #include "mmc_ops.h" #include "sd_ops.h" #include "sdio_ops.h" +#if defined(CONFIG_ARCH_GEN3) && defined(CONFIG_HW_MUTEXES) +#include "../host/sdhci.h" +#endif /* If the device is not responding */ #define MMC_CORE_TIMEOUT_MS (10 * 60 * 1000) /* 10 minute timeout */ @@ -201,6 +212,9 @@ pr_debug("%s: %d bytes transferred: %d\n", mmc_hostname(host), mrq->data->bytes_xfered, mrq->data->error); +#ifdef CONFIG_ARCH_GEN3 + trace_mmc_blk_rw_end(cmd->opcode, cmd->arg, mrq->data); +#endif } if (mrq->stop) { @@ -699,8 +713,14 @@ } } - if (!err && areq) + if (!err && areq) { +#ifdef CONFIG_ARCH_GEN3 + trace_mmc_blk_rw_start(areq->mrq->cmd->opcode, + areq->mrq->cmd->arg, + areq->mrq->data); +#endif start_err = __mmc_start_data_req(host, areq->mrq); + } if (host->areq) mmc_post_req(host, host->areq->mrq, 0); @@ -1055,7 +1075,23 @@ wake_up(&host->wq); spin_unlock_irqrestore(&host->lock, flags); remove_wait_queue(&host->wq, &wait); - +#if defined(CONFIG_ARCH_GEN3) && defined(CONFIG_HW_MUTEXES) + spin_lock_irqsave(&host->lock, flags); + /* + * mmc_claim_host is the start point of a set of MMC operations. + * Lock HW Mutex at the first time when a task owned the controller. + */ + if ((host->claimer == current) && + (host->claim_cnt == 1) && + ((host->caps2 & MMC_CAP2_RESCAN_ACTIVE) == 0)) { + spin_unlock_irqrestore(&host->lock, flags); + MMC_LOCK_HW_MUTEX(host); + } + else + { + spin_unlock_irqrestore(&host->lock, flags); + } +#endif if (pm) pm_runtime_get_sync(mmc_dev(host)); @@ -1084,6 +1120,16 @@ host->claimed = 0; host->claimer = NULL; spin_unlock_irqrestore(&host->lock, flags); +#if defined(CONFIG_ARCH_GEN3) && defined(CONFIG_HW_MUTEXES) + /* + * mmc_release_host is the end point of a set of MMC operations. + * Unlock the HW Mutex when a task doesn't own the controller + */ + if ((host->caps2 & MMC_CAP2_RESCAN_ACTIVE) == 0) + { + MMC_UNLOCK_HW_MUTEX(host); + } +#endif wake_up(&host->wq); pm_runtime_mark_last_busy(mmc_dev(host)); pm_runtime_put_autosuspend(mmc_dev(host)); @@ -2808,12 +2854,29 @@ goto out; } +#if (defined(CONFIG_ARCH_GEN3) && defined(CONFIG_HW_MUTEXES)) + host->caps2 |= MMC_CAP2_RESCAN_ACTIVE; /* Prevent Release and re-take HW_Mutex during rescan */ + + 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++) { if (!mmc_rescan_try_freq(host, max(freqs[i], host->f_min))) break; if (freqs[i] <= host->f_min) break; } +#if defined(CONFIG_ARCH_GEN3) + host->caps2 &= ~MMC_CAP2_RESCAN_ACTIVE; +#endif mmc_release_host(host); out: @@ -2826,13 +2889,17 @@ host->f_init = max(freqs[0], host->f_min); host->rescan_disable = 0; host->ios.power_mode = MMC_POWER_UNDEFINED; - +#ifndef CONFIG_ARCH_GEN3 + /* To avoid deadlock */ mmc_claim_host(host); +#endif if (host->caps2 & MMC_CAP2_NO_PRESCAN_POWERUP) mmc_power_off(host); else mmc_power_up(host, host->ocr_avail); +#ifndef CONFIG_ARCH_GEN3 mmc_release_host(host); +#endif mmc_gpiod_request_cd_irq(host); _mmc_detect_change(host, 0, false); @@ -2869,10 +2936,14 @@ mmc_bus_put(host); BUG_ON(host->card); - +#ifndef CONFIG_ARCH_GEN3 + /* To avoid deadlock */ mmc_claim_host(host); +#endif mmc_power_off(host); +#ifndef CONFIG_ARCH_GEN3 mmc_release_host(host); +#endif } int mmc_power_save_host(struct mmc_host *host)