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

Commit be05b187 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "mmc: bus: Handle error in case bus_ops suspend fails"

parents fb5047eb c691bdf5
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -169,6 +169,20 @@ static int mmc_bus_suspend(struct device *dev)
	if (mmc_bus_needs_resume(host))
		return 0;
	ret = host->bus_ops->suspend(host);

	/*
	 * bus_ops->suspend may fail due to some reason
	 * In such cases if we return error to PM framework
	 * from here without calling drv->resume then mmc
	 * request may get stuck since PM framework will assume
	 * that mmc bus is not suspended (because of error) and
	 * it won't call resume again.
	 *
	 * So in case of error call drv->resume.
	 */
	if (ret && dev->driver && drv->resume)
		drv->resume(card);

	return ret;
}

+31 −7
Original line number Diff line number Diff line
@@ -2370,7 +2370,7 @@ static int mmc_test_awake_ext_csd(struct mmc_host *host)

static int _mmc_suspend(struct mmc_host *host, bool is_suspend)
{
	int err = 0;
	int err = 0, ret;

	BUG_ON(!host);
	BUG_ON(!host->card);
@@ -2379,7 +2379,9 @@ static int _mmc_suspend(struct mmc_host *host, bool is_suspend)
	if (err) {
		pr_err("%s: %s: fail to suspend clock scaling (%d)\n",
			mmc_hostname(host), __func__, err);
		goto out;
		if (host->card->cmdq_init)
			wake_up(&host->cmdq_ctx.wait);
		return err;
	}

	mmc_claim_host(host);
@@ -2403,12 +2405,12 @@ static int _mmc_suspend(struct mmc_host *host, bool is_suspend)
	if (mmc_card_doing_bkops(host->card)) {
		err = mmc_stop_bkops(host->card);
		if (err)
			goto out;
			goto out_err;
	}

	err = mmc_flush_cache(host->card);
	if (err)
		goto out;
		goto out_err;

	if (mmc_can_sleepawake(host)) {
		/*
@@ -2425,16 +2427,38 @@ static int _mmc_suspend(struct mmc_host *host, bool is_suspend)
		err = mmc_deselect_cards(host);
	}

	if (!err) {
	if (err)
		goto out_err;
	mmc_power_off(host);
	mmc_card_set_suspended(host->card);

	goto out;

out_err:
	/*
	 * In case of err let's put controller back in cmdq mode and unhalt
	 * the controller.
	 * We expect cmdq_enable and unhalt won't return any error
	 * since it is anyway enabling few registers.
	 */
	if (host->card->cmdq_init) {
		mmc_host_clk_hold(host);
		ret = host->cmdq_ops->enable(host);
		if (ret)
			pr_err("%s: %s: enabling CMDQ mode failed (%d)\n",
				mmc_hostname(host), __func__, ret);
		mmc_host_clk_release(host);
		mmc_cmdq_halt(host, false);
	}

out:
	/* Kick CMDQ thread to process any requests came in while suspending */
	if (host->card->cmdq_init)
		wake_up(&host->cmdq_ctx.wait);

	mmc_release_host(host);
	if (err)
		mmc_resume_clk_scaling(host);
	return err;
}