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

Commit 551e3e65 authored by Talel Shenhar's avatar Talel Shenhar
Browse files

mmc: clk-scaling: fix invalid state handling during cmdq



This change fixes an issue that can happen for clock scaling
sequence during command-queue.

This is the sequence for scaling the clocks in case of
command queuing:

 1) Halt queue
 2) Check if state invalid
 3) Scale clocks
 4) Un-halt scale

In case step 2 fails (e.g. device state is different
than R1_STATE_TRAN), we should avoid scaling the clocks and
un-halt the queue. The issue was that step 4 was not
happening in case of invalid state, this change fixes it.

Change-Id: I308b0d6406631febe364d14de7551eb7f628cb40
Signed-off-by: default avatarTalel Shenhar <tatias@codeaurora.org>
parent 62eb03b5
Loading
Loading
Loading
Loading
+29 −26
Original line number Diff line number Diff line
@@ -346,7 +346,7 @@ static int mmc_devfreq_get_dev_status(struct device *dev,
	return 0;
}

static bool mmc_is_vaild_state_for_clk_scaling(struct mmc_host *host)
static bool mmc_is_valid_state_for_clk_scaling(struct mmc_host *host)
{
	struct mmc_card *card = host->card;
	u32 status;
@@ -422,6 +422,9 @@ int mmc_clk_update_freq(struct mmc_host *host,
			host->card->clk_scaling_lowest);
	}

	if (freq == host->clk_scaling.curr_freq)
		goto out;

	if (host->ops->notify_load) {
		err = host->ops->notify_load(host, state);
		if (err) {
@@ -431,20 +434,19 @@ int mmc_clk_update_freq(struct mmc_host *host,
		}
	}

	if (freq != host->clk_scaling.curr_freq) {
	if (cmdq_mode) {
		err = mmc_cmdq_halt_on_empty_queue(host);
		if (err) {
			pr_err("%s: %s: failed halting queue (%d)\n",
				mmc_hostname(host), __func__, err);
				goto error;
			goto halt_failed;
		}
	}

		if (!mmc_is_vaild_state_for_clk_scaling(host)) {
	if (!mmc_is_valid_state_for_clk_scaling(host)) {
		pr_debug("%s: invalid state for clock scaling - skipping",
			mmc_hostname(host));
			goto error;
		goto invalid_state;
	}

	err = host->bus_ops->change_bus_speed(host, &freq);
@@ -454,13 +456,14 @@ int mmc_clk_update_freq(struct mmc_host *host,
		pr_err("%s: %s: failed (%d) at freq=%lu\n",
			mmc_hostname(host), __func__, err, freq);

invalid_state:
	if (cmdq_mode) {
		if (mmc_cmdq_halt(host, false))
			pr_err("%s: %s: cmdq unhalt failed\n",
			mmc_hostname(host), __func__);
	}
	}
error:

halt_failed:
	if (err) {
		/* restore previous state */
		if (host->ops->notify_load)