diff options
Diffstat (limited to 'drivers/mmc/core/sdio.c')
| -rw-r--r-- | drivers/mmc/core/sdio.c | 135 | 
1 files changed, 30 insertions, 105 deletions
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index 80d89cff730..e636d9e99e4 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c @@ -363,7 +363,7 @@ static unsigned mmc_sdio_get_max_clock(struct mmc_card *card)  {  	unsigned max_dtr; -	if (mmc_card_highspeed(card)) { +	if (mmc_card_hs(card)) {  		/*  		 * The SDIO specification doesn't mention how  		 * the CIS transfer speed register relates to @@ -593,23 +593,28 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,  	struct mmc_card *card;  	int err;  	int retries = 10; +	u32 rocr = 0; +	u32 ocr_card = ocr;  	BUG_ON(!host);  	WARN_ON(!host->claimed); +	/* to query card if 1.8V signalling is supported */ +	if (mmc_host_uhs(host)) +		ocr |= R4_18V_PRESENT; +  try_again:  	if (!retries) {  		pr_warning("%s: Skipping voltage switch\n",  				mmc_hostname(host));  		ocr &= ~R4_18V_PRESENT; -		host->ocr &= ~R4_18V_PRESENT;  	}  	/*  	 * Inform the card of the voltage  	 */  	if (!powered_resume) { -		err = mmc_send_io_op_cond(host, host->ocr, &ocr); +		err = mmc_send_io_op_cond(host, ocr, &rocr);  		if (err)  			goto err;  	} @@ -632,8 +637,8 @@ try_again:  		goto err;  	} -	if ((ocr & R4_MEMORY_PRESENT) && -	    mmc_sd_get_cid(host, host->ocr & ocr, card->raw_cid, NULL) == 0) { +	if ((rocr & R4_MEMORY_PRESENT) && +	    mmc_sd_get_cid(host, ocr & rocr, card->raw_cid, NULL) == 0) {  		card->type = MMC_TYPE_SD_COMBO;  		if (oldcard && (oldcard->type != MMC_TYPE_SD_COMBO || @@ -663,8 +668,9 @@ try_again:  	 * systems that claim 1.8v signalling in fact do not support  	 * it.  	 */ -	if (!powered_resume && (ocr & R4_18V_PRESENT) && mmc_host_uhs(host)) { -		err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180); +	if (!powered_resume && (rocr & ocr & R4_18V_PRESENT)) { +		err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180, +					ocr);  		if (err == -EAGAIN) {  			sdio_reset(host);  			mmc_go_idle(host); @@ -674,12 +680,10 @@ try_again:  			goto try_again;  		} else if (err) {  			ocr &= ~R4_18V_PRESENT; -			host->ocr &= ~R4_18V_PRESENT;  		}  		err = 0;  	} else {  		ocr &= ~R4_18V_PRESENT; -		host->ocr &= ~R4_18V_PRESENT;  	}  	/* @@ -729,7 +733,6 @@ try_again:  		mmc_set_clock(host, card->cis.max_dtr);  		if (card->cccr.high_speed) { -			mmc_card_set_highspeed(card);  			mmc_set_timing(card->host, MMC_TIMING_SD_HS);  		} @@ -759,6 +762,7 @@ try_again:  		card = oldcard;  	} +	card->ocr = ocr_card;  	mmc_fixup_device(card, NULL);  	if (card->type == MMC_TYPE_SD_COMBO) { @@ -787,16 +791,13 @@ try_again:  		err = mmc_sdio_init_uhs_card(card);  		if (err)  			goto remove; - -		/* Card is an ultra-high-speed card */ -		mmc_card_set_uhs(card);  	} else {  		/*  		 * Switch to high-speed (if supported).  		 */  		err = sdio_enable_hs(card);  		if (err > 0) -			mmc_sd_go_highspeed(card); +			mmc_set_timing(card->host, MMC_TIMING_SD_HS);  		else if (err)  			goto remove; @@ -938,40 +939,21 @@ static int mmc_sdio_pre_suspend(struct mmc_host *host)   */  static int mmc_sdio_suspend(struct mmc_host *host)  { -	int i, err = 0; - -	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; -			err = pmops->suspend(&func->dev); -			if (err) -				break; -		} -	} -	while (err && --i >= 0) { -		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; -			pmops->resume(&func->dev); -		} -	} - -	if (!err && mmc_card_keep_power(host) && mmc_card_wake_sdio_irq(host)) { +	if (mmc_card_keep_power(host) && mmc_card_wake_sdio_irq(host)) {  		mmc_claim_host(host);  		sdio_disable_wide(host->card);  		mmc_release_host(host);  	} -	if (!err && !mmc_card_keep_power(host)) +	if (!mmc_card_keep_power(host))  		mmc_power_off(host); -	return err; +	return 0;  }  static int mmc_sdio_resume(struct mmc_host *host)  { -	int i, err = 0; +	int err = 0;  	BUG_ON(!host);  	BUG_ON(!host->card); @@ -981,8 +963,7 @@ static int mmc_sdio_resume(struct mmc_host *host)  	/* Restore power if needed */  	if (!mmc_card_keep_power(host)) { -		mmc_power_up(host); -		mmc_select_voltage(host, host->ocr); +		mmc_power_up(host, host->card->ocr);  		/*  		 * Tell runtime PM core we just powered up the card,  		 * since it still believes the card is powered off. @@ -1000,7 +981,7 @@ static int mmc_sdio_resume(struct mmc_host *host)  	if (mmc_card_is_removable(host) || !mmc_card_keep_power(host)) {  		sdio_reset(host);  		mmc_go_idle(host); -		err = mmc_sdio_init_card(host, host->ocr, host->card, +		err = mmc_sdio_init_card(host, host->card->ocr, host->card,  					mmc_card_keep_power(host));  	} else if (mmc_card_keep_power(host) && mmc_card_wake_sdio_irq(host)) {  		/* We may have switched to 1-bit mode during suspend */ @@ -1015,24 +996,6 @@ static int mmc_sdio_resume(struct mmc_host *host)  		wake_up_process(host->sdio_irq_thread);  	mmc_release_host(host); -	/* -	 * If the card looked to be the same as before suspending, then -	 * we proceed to resume all card functions.  If one of them returns -	 * an error then we simply return that error to the core and the -	 * card will be redetected as new.  It is the responsibility of -	 * the function driver to perform further tests with the extra -	 * knowledge it has of the card to confirm the card is indeed the -	 * same as before suspending (same MAC address for network cards, -	 * etc.) and return an error otherwise. -	 */ -	for (i = 0; !err && 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; -			err = pmops->resume(&func->dev); -		} -	} -  	host->pm_flags &= ~MMC_PM_KEEP_POWER;  	return err;  } @@ -1040,7 +1003,6 @@ static int mmc_sdio_resume(struct mmc_host *host)  static int mmc_sdio_power_restore(struct mmc_host *host)  {  	int ret; -	u32 ocr;  	BUG_ON(!host);  	BUG_ON(!host->card); @@ -1062,32 +1024,17 @@ static int mmc_sdio_power_restore(struct mmc_host *host)  	 * for OLPC SD8686 (which expects a [CMD5,5,3,7] init sequence), and  	 * harmless in other situations.  	 * -	 * With these steps taken, mmc_select_voltage() is also required to -	 * restore the correct voltage setting of the card.  	 */  	sdio_reset(host);  	mmc_go_idle(host);  	mmc_send_if_cond(host, host->ocr_avail); -	ret = mmc_send_io_op_cond(host, 0, &ocr); +	ret = mmc_send_io_op_cond(host, 0, NULL);  	if (ret)  		goto out; -	if (host->ocr_avail_sdio) -		host->ocr_avail = host->ocr_avail_sdio; - -	host->ocr = mmc_select_voltage(host, ocr & ~0x7F); -	if (!host->ocr) { -		ret = -EINVAL; -		goto out; -	} - -	if (mmc_host_uhs(host)) -		/* to query card if 1.8V signalling is supported */ -		host->ocr |= R4_18V_PRESENT; - -	ret = mmc_sdio_init_card(host, host->ocr, host->card, +	ret = mmc_sdio_init_card(host, host->card->ocr, host->card,  				mmc_card_keep_power(host));  	if (!ret && host->sdio_irqs)  		mmc_signal_sdio_irq(host); @@ -1108,7 +1055,7 @@ static int mmc_sdio_runtime_suspend(struct mmc_host *host)  static int mmc_sdio_runtime_resume(struct mmc_host *host)  {  	/* Restore power and re-initialize. */ -	mmc_power_up(host); +	mmc_power_up(host, host->card->ocr);  	return mmc_sdio_power_restore(host);  } @@ -1131,7 +1078,7 @@ static const struct mmc_bus_ops mmc_sdio_ops = {  int mmc_attach_sdio(struct mmc_host *host)  {  	int err, i, funcs; -	u32 ocr; +	u32 ocr, rocr;  	struct mmc_card *card;  	BUG_ON(!host); @@ -1145,23 +1092,13 @@ int mmc_attach_sdio(struct mmc_host *host)  	if (host->ocr_avail_sdio)  		host->ocr_avail = host->ocr_avail_sdio; -	/* -	 * Sanity check the voltages that the card claims to -	 * support. -	 */ -	if (ocr & 0x7F) { -		pr_warning("%s: card claims to support voltages " -		       "below the defined range. These will be ignored.\n", -		       mmc_hostname(host)); -		ocr &= ~0x7F; -	} -	host->ocr = mmc_select_voltage(host, ocr); +	rocr = mmc_select_voltage(host, ocr);  	/*  	 * Can we support the voltage(s) of the card(s)?  	 */ -	if (!host->ocr) { +	if (!rocr) {  		err = -EINVAL;  		goto err;  	} @@ -1169,22 +1106,10 @@ int mmc_attach_sdio(struct mmc_host *host)  	/*  	 * Detect and init the card.  	 */ -	if (mmc_host_uhs(host)) -		/* to query card if 1.8V signalling is supported */ -		host->ocr |= R4_18V_PRESENT; +	err = mmc_sdio_init_card(host, rocr, NULL, 0); +	if (err) +		goto err; -	err = mmc_sdio_init_card(host, host->ocr, NULL, 0); -	if (err) { -		if (err == -EAGAIN) { -			/* -			 * Retry initialization with S18R set to 0. -			 */ -			host->ocr &= ~R4_18V_PRESENT; -			err = mmc_sdio_init_card(host, host->ocr, NULL, 0); -		} -		if (err) -			goto err; -	}  	card = host->card;  	/*  | 
