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

Commit a1ccf2b5 authored by Sarthak Garg's avatar Sarthak Garg Committed by Gerrit - the friendly Code Review server
Browse files

mmc: core: Retry claim host in mmc_sd_detect



Use mmc_try_claim_host with a timeout instead of mmc_claim_host in
mmc_sd_detect. This is to ensure that mmc rescan work item is doesn't
get blocked on claim_host for longer period.
In the pm_suspend path, we cancel the mmc_rescan work item.
If this work item is already scheduled, suspend would be blocked till
mmc_rescan gets finished. In case, mmc_rescan is blocked on claim_host
lock, pm_suspend could get blocked for longer period.  This can result
in momentary UI freeze since pm_suspend is blocked for longer duration.
This change is to prevent this scenario.

Change-Id: Ib93bae6745a153bad3579ae42f46c3c3a7c1b95a
Signed-off-by: default avatarVeerabhadrarao Badiganti <vbadigan@codeaurora.org>
Signed-off-by: default avatarSarthak Garg <sartgarg@codeaurora.org>
parent 3717aafa
Loading
Loading
Loading
Loading
+41 −0
Original line number Diff line number Diff line
@@ -1644,6 +1644,47 @@ int __mmc_claim_host(struct mmc_host *host, struct mmc_ctx *ctx,
}
EXPORT_SYMBOL(__mmc_claim_host);

#if defined(CONFIG_SDC_QTI)
/**
 *   mmc_try_claim_host - try exclusively to claim a host
 *   and keep trying for given time, with a gap of 10ms
 *   @host: mmc host to claim
 *   @dealy_ms: delay in ms
 *
 *   Returns %1 if the host is claimed, %0 otherwise.
 */
int mmc_try_claim_host(struct mmc_host *host, struct mmc_ctx *ctx,
		     unsigned int delay_ms)
{
	int claimed_host = 0;
	struct task_struct *task = ctx ? NULL : current;
	unsigned long flags;
	int retry_cnt = delay_ms/10;
	bool pm = false;

	do {
		spin_lock_irqsave(&host->lock, flags);
		if (!host->claimed || mmc_ctx_matches(host, ctx, task)) {
			host->claimed = 1;
			mmc_ctx_set_claimer(host, ctx, task);
			host->claim_cnt += 1;
			claimed_host = 1;
			if (host->claim_cnt == 1)
				pm = true;
		}
		spin_unlock_irqrestore(&host->lock, flags);
		if (!claimed_host)
			mmc_delay(10);
	} while (!claimed_host && retry_cnt--);

	if (pm)
		pm_runtime_get_sync(mmc_dev(host));

	return claimed_host;
}
EXPORT_SYMBOL(mmc_try_claim_host);
#endif

/**
 *	mmc_release_host - release a host
 *	@host: mmc host to release
+4 −0
Original line number Diff line number Diff line
@@ -143,6 +143,10 @@ int mmc_set_blocklen(struct mmc_card *card, unsigned int blocklen);

int __mmc_claim_host(struct mmc_host *host, struct mmc_ctx *ctx,
		     atomic_t *abort);
#if defined(CONFIG_SDC_QTI)
int mmc_try_claim_host(struct mmc_host *host, struct mmc_ctx *ctx,
		unsigned int delay_ms);
#endif
void mmc_release_host(struct mmc_host *host);
void mmc_get_card(struct mmc_card *card, struct mmc_ctx *ctx);
void mmc_put_card(struct mmc_card *card, struct mmc_ctx *ctx);
+15 −1
Original line number Diff line number Diff line
@@ -1206,7 +1206,21 @@ static void mmc_sd_detect(struct mmc_host *host)
{
	int err;

#if defined(CONFIG_SDC_QTI)
	/*
	 * Try to acquire claim host. If failed to get the lock in 2 sec,
	 * just return; This is to ensure that when this call is invoked
	 * due to pm_suspend, not to block suspend for longer duration.
	 */
	pm_runtime_get_sync(&host->card->dev);
	if (!mmc_try_claim_host(host, NULL, 2000)) {
		pm_runtime_mark_last_busy(&host->card->dev);
		pm_runtime_put_autosuspend(&host->card->dev);
		return;
	}
#else
	 mmc_get_card(host->card, NULL);
#endif

	/*
	 * Just check if our card has been removed.