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

Commit bd7f791d 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: postpone runtime suspend in case BKOPS is required"

parents 713044ff 3fe7b483
Loading
Loading
Loading
Loading
+7 −7
Original line number Diff line number Diff line
@@ -1170,6 +1170,8 @@ int mmc_set_auto_bkops(struct mmc_card *card, bool enable)
			mmc_update_bkops_auto_off(&card->bkops.stats);
		}
		card->ext_csd.bkops_en = bkops_en;
		pr_debug("%s: %s: bkops state %x\n",
				mmc_hostname(card->host), __func__, bkops_en);
	}
out:
	return ret;
@@ -1189,9 +1191,7 @@ void mmc_check_bkops(struct mmc_card *card)

	BUG_ON(!card);

	if (unlikely(!mmc_card_configured_manual_bkops(card)))
		return;
	if (mmc_card_doing_bkops(card) || mmc_card_doing_auto_bkops(card))
	if (mmc_card_doing_bkops(card))
		return;

	err = mmc_read_bkops_status(card);
@@ -1201,12 +1201,12 @@ void mmc_check_bkops(struct mmc_card *card)
		return;
	}

	card->bkops.needs_check = false;

	mmc_update_bkops_level(&card->bkops.stats,
				card->ext_csd.raw_bkops_status);
	if (card->ext_csd.raw_bkops_status < EXT_CSD_BKOPS_LEVEL_2)
		return;

	card->bkops.needs_manual = true;
	card->bkops.needs_bkops = card->ext_csd.raw_bkops_status > 0;
}
EXPORT_SYMBOL(mmc_check_bkops);

@@ -1237,7 +1237,7 @@ void mmc_start_manual_bkops(struct mmc_card *card)
	} else {
		mmc_card_set_doing_bkops(card);
		mmc_update_bkops_start(&card->bkops.stats);
		card->bkops.needs_manual = false;
		card->bkops.needs_bkops = false;
	}
}
EXPORT_SYMBOL(mmc_start_manual_bkops);
+64 −0
Original line number Diff line number Diff line
@@ -2576,6 +2576,64 @@ static int mmc_resume(struct mmc_host *host)
	return err;
}

#define MAX_DEFER_SUSPEND_COUNTER 20
static bool mmc_process_bkops(struct mmc_host *host)
{
	int err = 0;
	bool is_running = false;
	u32 status;

	mmc_claim_host(host);
	if (mmc_card_cmdq(host->card)) {
		BUG_ON(host->cmdq_ctx.active_reqs);

		err = mmc_cmdq_halt(host, true);
		if (err) {
			pr_err("%s: halt: failed: %d\n", __func__, err);
			goto unhalt;
		}
	}

	if (mmc_card_doing_bkops(host->card)) {
		/* check that manual bkops finished */
		err = mmc_send_status(host->card, &status);
		if (err) {
			pr_err("%s: Get card status fail\n", __func__);
			goto unhalt;
		}
		if (R1_CURRENT_STATE(status) != R1_STATE_PRG) {
			mmc_card_clr_doing_bkops(host->card);
			goto unhalt;
		}
	} else {
		mmc_check_bkops(host->card);
	}

	if (host->card->bkops.needs_bkops &&
			!mmc_card_support_auto_bkops(host->card))
		mmc_start_manual_bkops(host->card);

unhalt:
	if (mmc_card_cmdq(host->card)) {
		err = mmc_cmdq_halt(host, false);
		if (err)
			pr_err("%s: unhalt: failed: %d\n", __func__, err);
	}
	mmc_release_host(host);

	if (host->card->bkops.needs_bkops ||
			mmc_card_doing_bkops(host->card)) {
		if (host->card->bkops.retry_counter++ <
				MAX_DEFER_SUSPEND_COUNTER) {
			host->card->bkops.needs_check = true;
			is_running = true;
		} else {
			host->card->bkops.retry_counter = 0;
		}
	}
	return is_running;
}

/*
 * Callback for runtime_suspend.
 */
@@ -2587,6 +2645,12 @@ static int mmc_runtime_suspend(struct mmc_host *host)
	if (!(host->caps & MMC_CAP_AGGRESSIVE_PM))
		return 0;

	if (mmc_process_bkops(host)) {
		pm_runtime_mark_last_busy(&host->card->dev);
		pr_debug("%s: defered, need bkops\n", __func__);
		return -EBUSY;
	}

	err = _mmc_suspend(host, true);
	if (err)
		pr_err("%s: error %d doing aggessive suspend\n",
+3 −3
Original line number Diff line number Diff line
/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
/* Copyright (c) 2015-2016 The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -876,8 +876,8 @@ skip_cqterri:
			 * exception once the queue is empty
			 */
			BUG_ON(!mmc->card);
			if (mmc_card_configured_manual_bkops(mmc->card) &&
			    !mmc_card_configured_auto_bkops(mmc->card))
			if (mmc_card_configured_manual_bkops(mmc->card) ||
			    mmc_card_configured_auto_bkops(mmc->card))
				mmc->card->bkops.needs_check = true;

			mrq->cmdq_req->resp_err = true;
+2 −1
Original line number Diff line number Diff line
@@ -324,7 +324,8 @@ struct mmc_bkops_stats {
struct mmc_bkops_info {
	struct mmc_bkops_stats stats;
	bool needs_check;
	bool needs_manual;
	bool needs_bkops;
	u32  retry_counter;
};

enum mmc_pon_type {