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

Commit 12896a6f 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: extend SDR104 workaround for other paths"

parents f5b9a7e2 b8189b17
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -1707,6 +1707,8 @@ static int mmc_blk_cmd_recovery(struct mmc_card *card, struct request *req,

	/* We couldn't get a response from the card.  Give up. */
	if (err) {
		if (card->err_in_sdr104)
			return ERR_RETRY;
		/* Check if the card is removed */
		if (mmc_detect_card_removed(card->host))
			return ERR_NOMEDIUM;
@@ -2197,7 +2199,8 @@ static int mmc_blk_err_check(struct mmc_card *card,
	     brq->data.error == -ETIMEDOUT ||
	     brq->cmd.error == -EILSEQ ||
	     brq->cmd.error == -EIO ||
	     brq->cmd.error == -ETIMEDOUT))
	     brq->cmd.error == -ETIMEDOUT ||
	     brq->sbc.error))
		card->err_in_sdr104 = true;

	/*
+48 −10
Original line number Diff line number Diff line
@@ -464,6 +464,22 @@ out:
}
EXPORT_SYMBOL(mmc_clk_update_freq);

void mmc_recovery_fallback_lower_speed(struct mmc_host *host)
{
	if (!host->card)
		return;

	if (host->sdr104_wa && mmc_card_sd(host->card) &&
	    (host->ios.timing == MMC_TIMING_UHS_SDR104) &&
	    !host->card->sdr104_blocked) {
		pr_err("%s: %s: blocked SDR104, lower the bus-speed (SDR50 / DDR50)\n",
			mmc_hostname(host), __func__);
		mmc_host_clear_sdr104(host);
		mmc_hw_reset(host);
		host->card->sdr104_blocked = true;
	}
}

static int mmc_devfreq_set_target(struct device *dev,
				unsigned long *freq, u32 devfreq_flags)
{
@@ -510,6 +526,9 @@ static int mmc_devfreq_set_target(struct device *dev,
	if (abort)
		goto out;

	if (mmc_card_sd(host->card) && host->card->sdr104_blocked)
		goto rel_host;

	/*
	 * In case we were able to claim host there is no need to
	 * defer the frequency change. It will be done now
@@ -518,15 +537,18 @@ static int mmc_devfreq_set_target(struct device *dev,

	mmc_host_clk_hold(host);
	err = mmc_clk_update_freq(host, *freq, clk_scaling->state);
	if (err && err != -EAGAIN)
	if (err && err != -EAGAIN) {
		pr_err("%s: clock scale to %lu failed with error %d\n",
			mmc_hostname(host), *freq, err);
	else
		mmc_recovery_fallback_lower_speed(host);
	} else {
		pr_debug("%s: clock change to %lu finished successfully (%s)\n",
			mmc_hostname(host), *freq, current->comm);
	}


	mmc_host_clk_release(host);
rel_host:
	mmc_release_host(host);
out:
	return err;
@@ -547,6 +569,9 @@ void mmc_deferred_scaling(struct mmc_host *host)
	if (!host->clk_scaling.enable)
		return;

	if (mmc_card_sd(host->card) && host->card->sdr104_blocked)
		return;

	spin_lock_bh(&host->clk_scaling.lock);

	if (host->clk_scaling.clk_scaling_in_progress ||
@@ -567,13 +592,15 @@ void mmc_deferred_scaling(struct mmc_host *host)

	err = mmc_clk_update_freq(host, target_freq,
		host->clk_scaling.state);
	if (err && err != -EAGAIN)
	if (err && err != -EAGAIN) {
		pr_err("%s: failed on deferred scale clocks (%d)\n",
			mmc_hostname(host), err);
	else
		mmc_recovery_fallback_lower_speed(host);
	} else {
		pr_debug("%s: clocks were successfully scaled to %lu (%s)\n",
			mmc_hostname(host),
			target_freq, current->comm);
	}
	host->clk_scaling.clk_scaling_in_progress = false;
	atomic_dec(&host->clk_scaling.devfreq_abort);
}
@@ -1474,8 +1501,13 @@ static void mmc_wait_for_req_done(struct mmc_host *host,
			}
		}
		if (!cmd->error || !cmd->retries ||
		    mmc_card_removed(host->card))
		    mmc_card_removed(host->card)) {
			if (cmd->error && !cmd->retries &&
			     cmd->opcode != MMC_SEND_STATUS &&
			     cmd->opcode != MMC_SEND_TUNING_BLOCK)
				mmc_recovery_fallback_lower_speed(host);
			break;
		}

		mmc_retune_recheck(host);

@@ -4043,12 +4075,18 @@ int _mmc_detect_card_removed(struct mmc_host *host)
	}

	if (ret) {
		if (host->ops->get_cd && host->ops->get_cd(host)) {
			mmc_recovery_fallback_lower_speed(host);
			ret = 0;
		} else {
			mmc_card_set_removed(host->card);
			if (host->card->sdr104_blocked) {
				mmc_host_set_sdr104(host);
				host->card->sdr104_blocked = false;
			}
		pr_debug("%s: card remove detected\n", mmc_hostname(host));
			pr_debug("%s: card remove detected\n",
					mmc_hostname(host));
		}
	}

	return ret;
+1 −0
Original line number Diff line number Diff line
@@ -223,6 +223,7 @@ extern void mmc_cmdq_clk_scaling_start_busy(struct mmc_host *host,
	bool lock_needed);
extern void mmc_cmdq_clk_scaling_stop_busy(struct mmc_host *host,
	bool lock_needed, bool is_cmdq_dcmd);
extern void mmc_recovery_fallback_lower_speed(struct mmc_host *host);

/**
 *	mmc_claim_host - exclusively claim a host