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

Commit 2de00cb2 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 7f1ad4a9 8cd402a5
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -1718,6 +1718,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;
@@ -2208,7 +2210,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;

	/*
+55 −10
Original line number Diff line number Diff line
@@ -456,6 +456,22 @@ int mmc_clk_update_freq(struct mmc_host *host,
}
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)
{
@@ -507,6 +523,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
@@ -515,15 +534,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;
@@ -544,6 +566,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 ||
@@ -564,13 +589,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);
}
@@ -1540,8 +1567,13 @@ void mmc_wait_for_req_done(struct mmc_host *host, struct mmc_request *mrq)
			}
		}
		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);

@@ -2368,6 +2400,13 @@ void mmc_ungate_clock(struct mmc_host *host)
		WARN_ON(host->ios.clock);
		/* This call will also set host->clk_gated to false */
		__mmc_set_clock(host, host->clk_old);
		/*
		 * We have seen that host controller's clock tuning circuit may
		 * go out of sync if controller clocks are gated.
		 * To workaround this issue, we are triggering retuning of the
		 * tuning circuit after ungating the controller clocks.
		 */
		mmc_retune_needed(host);
	}
}

@@ -4189,12 +4228,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
@@ -232,6 +232,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