Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d10b0c95 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "mmc: core: Fix deadlock in suspend & rescan path"

parents 4061ccec 562dd2c5
Loading
Loading
Loading
Loading
+10 −9
Original line number Diff line number Diff line
@@ -1640,6 +1640,10 @@ EXPORT_SYMBOL(mmc_start_req);
 */
void mmc_wait_for_req(struct mmc_host *host, struct mmc_request *mrq)
{
#ifdef CONFIG_MMC_BLOCK_DEFERRED_RESUME
	if (mmc_bus_needs_resume(host))
		mmc_resume_bus(host);
#endif
	__mmc_start_req(host, mrq);
	mmc_wait_for_req_done(host, mrq);
}
@@ -2773,7 +2777,6 @@ int mmc_resume_bus(struct mmc_host *host)
	pr_debug("%s: Starting deferred resume\n", mmc_hostname(host));
	spin_lock_irqsave(&host->lock, flags);
	host->bus_resume_flags &= ~MMC_BUSRESUME_NEEDS_RESUME;
	host->rescan_disable = 0;
	spin_unlock_irqrestore(&host->lock, flags);

	mmc_bus_get(host);
@@ -2791,9 +2794,6 @@ int mmc_resume_bus(struct mmc_host *host)
		}
	}

	if (host->bus_ops->detect && !host->bus_dead)
		host->bus_ops->detect(host);

	mmc_bus_put(host);
	pr_debug("%s: Deferred resume completed\n", mmc_hostname(host));
	return 0;
@@ -3753,6 +3753,7 @@ EXPORT_SYMBOL(mmc_detect_card_removed);

void mmc_rescan(struct work_struct *work)
{
	unsigned long flags;
	struct mmc_host *host =
		container_of(work, struct mmc_host, detect.work);

@@ -3761,8 +3762,12 @@ void mmc_rescan(struct work_struct *work)
		host->trigger_card_event = false;
	}

	if (host->rescan_disable)
	spin_lock_irqsave(&host->lock, flags);
	if (host->rescan_disable) {
		spin_unlock_irqrestore(&host->lock, flags);
		return;
	}
	spin_unlock_irqrestore(&host->lock, flags);

	/* If there is a non-removable card registered, only scan once */
	if ((host->caps & MMC_CAP_NONREMOVABLE) && host->rescan_entered)
@@ -4005,10 +4010,6 @@ int mmc_pm_notify(struct notifier_block *notify_block,
	case PM_SUSPEND_PREPARE:
	case PM_RESTORE_PREPARE:
		spin_lock_irqsave(&host->lock, flags);
		if (mmc_bus_needs_resume(host)) {
			spin_unlock_irqrestore(&host->lock, flags);
			break;
		}
		host->rescan_disable = 1;
		spin_unlock_irqrestore(&host->lock, flags);
		cancel_delayed_work_sync(&host->detect);
+7 −2
Original line number Diff line number Diff line
@@ -196,6 +196,9 @@
#define MAX_DRV_TYPES_SUPPORTED_HS200	4
#define MSM_AUTOSUSPEND_DELAY_MS 100

/* Timeout value to avoid infinite waiting for pwr_irq */
#define MSM_PWR_IRQ_TIMEOUT_MS 5000

static const u32 tuning_block_64[] = {
	0x00FF0FFF, 0xCCC3CCFF, 0xFFCC3CC3, 0xEFFEFFFE,
	0xDDFFDFFF, 0xFBFFFBFF, 0xFF7FFFBF, 0xEFBDF777,
@@ -2578,8 +2581,10 @@ static void sdhci_msm_check_power_status(struct sdhci_host *host, u32 req_type)
	 */
	if (done)
		init_completion(&msm_host->pwr_irq_completion);
	else
		wait_for_completion(&msm_host->pwr_irq_completion);
	else if (!wait_for_completion_timeout(&msm_host->pwr_irq_completion,
				msecs_to_jiffies(MSM_PWR_IRQ_TIMEOUT_MS)))
		__WARN_printf("%s: request(%d) timed out waiting for pwr_irq\n",
					mmc_hostname(host->mmc), req_type);

	pr_debug("%s: %s: request %d done\n", mmc_hostname(host->mmc),
			__func__, req_type);