diff options
Diffstat (limited to 'drivers/mmc/core/sdio.c')
| -rw-r--r-- | drivers/mmc/core/sdio.c | 28 | 
1 files changed, 27 insertions, 1 deletions
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index 26cabd53ddc5..ebb387aa5158 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c @@ -1048,9 +1048,35 @@ static int mmc_sdio_runtime_resume(struct mmc_host *host)  	return ret;  } +/* + * SDIO HW reset + * + * Returns 0 if the HW reset was executed synchronously, returns 1 if the HW + * reset was asynchronously scheduled, else a negative error code. + */  static int mmc_sdio_hw_reset(struct mmc_host *host)  { -	mmc_power_cycle(host, host->card->ocr); +	struct mmc_card *card = host->card; + +	/* +	 * In case the card is shared among multiple func drivers, reset the +	 * card through a rescan work. In this way it will be removed and +	 * re-detected, thus all func drivers becomes informed about it. +	 */ +	if (atomic_read(&card->sdio_funcs_probed) > 1) { +		if (mmc_card_removed(card)) +			return 1; +		host->rescan_entered = 0; +		mmc_card_set_removed(card); +		_mmc_detect_change(host, 0, false); +		return 1; +	} + +	/* +	 * A single func driver has been probed, then let's skip the heavy +	 * hotplug dance above and execute the reset immediately. +	 */ +	mmc_power_cycle(host, card->ocr);  	return mmc_sdio_reinit_card(host);  }  |