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

Commit 8d1ffc8c authored by Ulf Hansson's avatar Ulf Hansson
Browse files

mmc: core: Keep host claimed while invoking mmc_power_off|up()



As mmc_claim_host() invokes pm_runtime_get_sync() for the mmc host device,
it's important that the host is kept claimed for *all* accesses to it via
the host_ops callbacks.

In some code paths for SDIO, particularly related to the PM support,
mmc_power_off|up() is invoked without keeping the host claimed. Let's fix
these.

Moreover, mmc_start|stop_host() also invokes mmc_power_off|up() without
claiming the host, let's fix these as well.

Signed-off-by: default avatarUlf Hansson <ulf.hansson@linaro.org>
Acked-by: default avatarKishon Vijay Abraham I <kishon@ti.com>
parent 0cd2f044
Loading
Loading
Loading
Loading
+6 −0
Original line number Original line Diff line number Diff line
@@ -2633,10 +2633,14 @@ void mmc_start_host(struct mmc_host *host)
	host->f_init = max(freqs[0], host->f_min);
	host->f_init = max(freqs[0], host->f_min);
	host->rescan_disable = 0;
	host->rescan_disable = 0;
	host->ios.power_mode = MMC_POWER_UNDEFINED;
	host->ios.power_mode = MMC_POWER_UNDEFINED;

	mmc_claim_host(host);
	if (host->caps2 & MMC_CAP2_NO_PRESCAN_POWERUP)
	if (host->caps2 & MMC_CAP2_NO_PRESCAN_POWERUP)
		mmc_power_off(host);
		mmc_power_off(host);
	else
	else
		mmc_power_up(host, host->ocr_avail);
		mmc_power_up(host, host->ocr_avail);
	mmc_release_host(host);

	mmc_gpiod_request_cd_irq(host);
	mmc_gpiod_request_cd_irq(host);
	_mmc_detect_change(host, 0, false);
	_mmc_detect_change(host, 0, false);
}
}
@@ -2674,7 +2678,9 @@ void mmc_stop_host(struct mmc_host *host)


	BUG_ON(host->card);
	BUG_ON(host->card);


	mmc_claim_host(host);
	mmc_power_off(host);
	mmc_power_off(host);
	mmc_release_host(host);
}
}


int mmc_power_save_host(struct mmc_host *host)
int mmc_power_save_host(struct mmc_host *host)
+15 −5
Original line number Original line Diff line number Diff line
@@ -897,11 +897,10 @@ static int mmc_sdio_pre_suspend(struct mmc_host *host)
 */
 */
static int mmc_sdio_suspend(struct mmc_host *host)
static int mmc_sdio_suspend(struct mmc_host *host)
{
{
	if (mmc_card_keep_power(host) && mmc_card_wake_sdio_irq(host)) {
	mmc_claim_host(host);
	mmc_claim_host(host);

	if (mmc_card_keep_power(host) && mmc_card_wake_sdio_irq(host))
		sdio_disable_wide(host->card);
		sdio_disable_wide(host->card);
		mmc_release_host(host);
	}


	if (!mmc_card_keep_power(host)) {
	if (!mmc_card_keep_power(host)) {
		mmc_power_off(host);
		mmc_power_off(host);
@@ -910,6 +909,8 @@ static int mmc_sdio_suspend(struct mmc_host *host)
		mmc_retune_needed(host);
		mmc_retune_needed(host);
	}
	}


	mmc_release_host(host);

	return 0;
	return 0;
}
}


@@ -1018,15 +1019,24 @@ static int mmc_sdio_power_restore(struct mmc_host *host)
static int mmc_sdio_runtime_suspend(struct mmc_host *host)
static int mmc_sdio_runtime_suspend(struct mmc_host *host)
{
{
	/* No references to the card, cut the power to it. */
	/* No references to the card, cut the power to it. */
	mmc_claim_host(host);
	mmc_power_off(host);
	mmc_power_off(host);
	mmc_release_host(host);

	return 0;
	return 0;
}
}


static int mmc_sdio_runtime_resume(struct mmc_host *host)
static int mmc_sdio_runtime_resume(struct mmc_host *host)
{
{
	int ret;

	/* Restore power and re-initialize. */
	/* Restore power and re-initialize. */
	mmc_claim_host(host);
	mmc_power_up(host, host->card->ocr);
	mmc_power_up(host, host->card->ocr);
	return mmc_sdio_power_restore(host);
	ret = mmc_sdio_power_restore(host);
	mmc_release_host(host);

	return ret;
}
}


static int mmc_sdio_reset(struct mmc_host *host)
static int mmc_sdio_reset(struct mmc_host *host)