diff options
Diffstat (limited to 'drivers/mmc/core/sdio.c')
| -rw-r--r-- | drivers/mmc/core/sdio.c | 28 | 
1 files changed, 22 insertions, 6 deletions
| diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index 0fda7784cab2..3eb94ac2712e 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c @@ -985,21 +985,37 @@ out:   */  static int mmc_sdio_pre_suspend(struct mmc_host *host)  { -	int i, err = 0; +	int i;  	for (i = 0; i < host->card->sdio_funcs; i++) {  		struct sdio_func *func = host->card->sdio_func[i];  		if (func && sdio_func_present(func) && func->dev.driver) {  			const struct dev_pm_ops *pmops = func->dev.driver->pm; -			if (!pmops || !pmops->suspend || !pmops->resume) { +			if (!pmops || !pmops->suspend || !pmops->resume)  				/* force removal of entire card in that case */ -				err = -ENOSYS; -				break; -			} +				goto remove;  		}  	} -	return err; +	return 0; + +remove: +	if (!mmc_card_is_removable(host)) { +		dev_warn(mmc_dev(host), +			 "missing suspend/resume ops for non-removable SDIO card\n"); +		/* Don't remove a non-removable card - we can't re-detect it. */ +		return 0; +	} + +	/* Remove the SDIO card and let it be re-detected later on. */ +	mmc_sdio_remove(host); +	mmc_claim_host(host); +	mmc_detach_bus(host); +	mmc_power_off(host); +	mmc_release_host(host); +	host->pm_flags = 0; + +	return 0;  }  /* | 
