diff options
Diffstat (limited to 'drivers/mmc/core')
| -rw-r--r-- | drivers/mmc/core/bus.c | 41 | ||||
| -rw-r--r-- | drivers/mmc/core/cd-gpio.c | 1 | ||||
| -rw-r--r-- | drivers/mmc/core/core.c | 74 | ||||
| -rw-r--r-- | drivers/mmc/core/mmc.c | 30 | ||||
| -rw-r--r-- | drivers/mmc/core/sdio_bus.c | 12 | 
5 files changed, 83 insertions, 75 deletions
diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c index 5d011a39dff..c60cee92a2b 100644 --- a/drivers/mmc/core/bus.c +++ b/drivers/mmc/core/bus.c @@ -122,14 +122,14 @@ static int mmc_bus_remove(struct device *dev)  	return 0;  } -static int mmc_bus_suspend(struct device *dev, pm_message_t state) +static int mmc_bus_suspend(struct device *dev)  {  	struct mmc_driver *drv = to_mmc_driver(dev->driver);  	struct mmc_card *card = mmc_dev_to_card(dev);  	int ret = 0;  	if (dev->driver && drv->suspend) -		ret = drv->suspend(card, state); +		ret = drv->suspend(card);  	return ret;  } @@ -165,20 +165,14 @@ static int mmc_runtime_idle(struct device *dev)  	return pm_runtime_suspend(dev);  } +#endif /* !CONFIG_PM_RUNTIME */ +  static const struct dev_pm_ops mmc_bus_pm_ops = { -	.runtime_suspend	= mmc_runtime_suspend, -	.runtime_resume		= mmc_runtime_resume, -	.runtime_idle		= mmc_runtime_idle, +	SET_RUNTIME_PM_OPS(mmc_runtime_suspend, mmc_runtime_resume, +			mmc_runtime_idle) +	SET_SYSTEM_SLEEP_PM_OPS(mmc_bus_suspend, mmc_bus_resume)  }; -#define MMC_PM_OPS_PTR	(&mmc_bus_pm_ops) - -#else /* !CONFIG_PM_RUNTIME */ - -#define MMC_PM_OPS_PTR	NULL - -#endif /* !CONFIG_PM_RUNTIME */ -  static struct bus_type mmc_bus_type = {  	.name		= "mmc",  	.dev_attrs	= mmc_dev_attrs, @@ -186,9 +180,7 @@ static struct bus_type mmc_bus_type = {  	.uevent		= mmc_bus_uevent,  	.probe		= mmc_bus_probe,  	.remove		= mmc_bus_remove, -	.suspend	= mmc_bus_suspend, -	.resume		= mmc_bus_resume, -	.pm		= MMC_PM_OPS_PTR, +	.pm		= &mmc_bus_pm_ops,  };  int mmc_register_bus(void) @@ -267,6 +259,15 @@ int mmc_add_card(struct mmc_card *card)  {  	int ret;  	const char *type; +	const char *uhs_bus_speed_mode = ""; +	static const char *const uhs_speeds[] = { +		[UHS_SDR12_BUS_SPEED] = "SDR12 ", +		[UHS_SDR25_BUS_SPEED] = "SDR25 ", +		[UHS_SDR50_BUS_SPEED] = "SDR50 ", +		[UHS_SDR104_BUS_SPEED] = "SDR104 ", +		[UHS_DDR50_BUS_SPEED] = "DDR50 ", +	}; +  	dev_set_name(&card->dev, "%s:%04x", mmc_hostname(card->host), card->rca); @@ -296,6 +297,10 @@ int mmc_add_card(struct mmc_card *card)  		break;  	} +	if (mmc_sd_card_uhs(card) && +		(card->sd_bus_speed < ARRAY_SIZE(uhs_speeds))) +		uhs_bus_speed_mode = uhs_speeds[card->sd_bus_speed]; +  	if (mmc_host_is_spi(card->host)) {  		pr_info("%s: new %s%s%s card on SPI\n",  			mmc_hostname(card->host), @@ -303,13 +308,13 @@ int mmc_add_card(struct mmc_card *card)  			mmc_card_ddr_mode(card) ? "DDR " : "",  			type);  	} else { -		pr_info("%s: new %s%s%s%s card at address %04x\n", +		pr_info("%s: new %s%s%s%s%s card at address %04x\n",  			mmc_hostname(card->host),  			mmc_card_uhs(card) ? "ultra high speed " :  			(mmc_card_highspeed(card) ? "high speed " : ""),  			(mmc_card_hs200(card) ? "HS200 " : ""),  			mmc_card_ddr_mode(card) ? "DDR " : "", -			type, card->rca); +			uhs_bus_speed_mode, type, card->rca);  	}  #ifdef CONFIG_DEBUG_FS diff --git a/drivers/mmc/core/cd-gpio.c b/drivers/mmc/core/cd-gpio.c index 29de31e260d..2c14be73254 100644 --- a/drivers/mmc/core/cd-gpio.c +++ b/drivers/mmc/core/cd-gpio.c @@ -12,6 +12,7 @@  #include <linux/gpio.h>  #include <linux/interrupt.h>  #include <linux/jiffies.h> +#include <linux/mmc/cd-gpio.h>  #include <linux/mmc/host.h>  #include <linux/module.h>  #include <linux/slab.h> diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 14f262e9246..ba821fe70bc 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -527,10 +527,14 @@ void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card)  		if (data->flags & MMC_DATA_WRITE)  			/* -			 * The limit is really 250 ms, but that is -			 * insufficient for some crappy cards. +			 * The MMC spec "It is strongly recommended +			 * for hosts to implement more than 500ms +			 * timeout value even if the card indicates +			 * the 250ms maximum busy length."  Even the +			 * previous value of 300ms is known to be +			 * insufficient for some cards.  			 */ -			limit_us = 300000; +			limit_us = 3000000;  		else  			limit_us = 100000; @@ -1405,7 +1409,10 @@ static unsigned int mmc_mmc_erase_timeout(struct mmc_card *card,  {  	unsigned int erase_timeout; -	if (card->ext_csd.erase_group_def & 1) { +	if (arg == MMC_DISCARD_ARG || +	    (arg == MMC_TRIM_ARG && card->ext_csd.rev >= 6)) { +		erase_timeout = card->ext_csd.trim_timeout; +	} else if (card->ext_csd.erase_group_def & 1) {  		/* High Capacity Erase Group Size uses HC timeouts */  		if (arg == MMC_TRIM_ARG)  			erase_timeout = card->ext_csd.trim_timeout; @@ -1677,8 +1684,6 @@ int mmc_can_trim(struct mmc_card *card)  {  	if (card->ext_csd.sec_feature_support & EXT_CSD_SEC_GB_CL_EN)  		return 1; -	if (mmc_can_discard(card)) -		return 1;  	return 0;  }  EXPORT_SYMBOL(mmc_can_trim); @@ -1697,6 +1702,8 @@ EXPORT_SYMBOL(mmc_can_discard);  int mmc_can_sanitize(struct mmc_card *card)  { +	if (!mmc_can_trim(card) && !mmc_can_erase(card)) +		return 0;  	if (card->ext_csd.sec_feature_support & EXT_CSD_SEC_SANITIZE)  		return 1;  	return 0; @@ -2231,6 +2238,7 @@ int mmc_cache_ctrl(struct mmc_host *host, u8 enable)  			mmc_card_is_removable(host))  		return err; +	mmc_claim_host(host);  	if (card && mmc_card_mmc(card) &&  			(card->ext_csd.cache_size > 0)) {  		enable = !!enable; @@ -2248,6 +2256,7 @@ int mmc_cache_ctrl(struct mmc_host *host, u8 enable)  				card->ext_csd.cache_ctrl = enable;  		}  	} +	mmc_release_host(host);  	return err;  } @@ -2265,49 +2274,32 @@ int mmc_suspend_host(struct mmc_host *host)  	cancel_delayed_work(&host->detect);  	mmc_flush_scheduled_work(); -	if (mmc_try_claim_host(host)) { -		err = mmc_cache_ctrl(host, 0); -		mmc_release_host(host); -	} else { -		err = -EBUSY; -	} +	err = mmc_cache_ctrl(host, 0);  	if (err)  		goto out;  	mmc_bus_get(host);  	if (host->bus_ops && !host->bus_dead) { -		/* -		 * A long response time is not acceptable for device drivers -		 * when doing suspend. Prevent mmc_claim_host in the suspend -		 * sequence, to potentially wait "forever" by trying to -		 * pre-claim the host. -		 */ -		if (mmc_try_claim_host(host)) { -			if (host->bus_ops->suspend) { -				err = host->bus_ops->suspend(host); -			} -			mmc_release_host(host); +		if (host->bus_ops->suspend) +			err = host->bus_ops->suspend(host); -			if (err == -ENOSYS || !host->bus_ops->resume) { -				/* -				 * We simply "remove" the card in this case. -				 * It will be redetected on resume.  (Calling -				 * bus_ops->remove() with a claimed host can -				 * deadlock.) -				 */ -				if (host->bus_ops->remove) -					host->bus_ops->remove(host); -				mmc_claim_host(host); -				mmc_detach_bus(host); -				mmc_power_off(host); -				mmc_release_host(host); -				host->pm_flags = 0; -				err = 0; -			} -		} else { -			err = -EBUSY; +		if (err == -ENOSYS || !host->bus_ops->resume) { +			/* +			 * We simply "remove" the card in this case. +			 * It will be redetected on resume.  (Calling +			 * bus_ops->remove() with a claimed host can +			 * deadlock.) +			 */ +			if (host->bus_ops->remove) +				host->bus_ops->remove(host); +			mmc_claim_host(host); +			mmc_detach_bus(host); +			mmc_power_off(host); +			mmc_release_host(host); +			host->pm_flags = 0; +			err = 0;  		}  	}  	mmc_bus_put(host); diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 02914d609a9..54df5adc041 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -695,6 +695,11 @@ static int mmc_select_powerclass(struct mmc_card *card,  		else if (host->ios.clock <= 200000000)  			index = EXT_CSD_PWR_CL_200_195;  		break; +	case MMC_VDD_27_28: +	case MMC_VDD_28_29: +	case MMC_VDD_29_30: +	case MMC_VDD_30_31: +	case MMC_VDD_31_32:  	case MMC_VDD_32_33:  	case MMC_VDD_33_34:  	case MMC_VDD_34_35: @@ -1111,11 +1116,10 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,  		ext_csd_bits = (bus_width == MMC_BUS_WIDTH_8) ?  				EXT_CSD_BUS_WIDTH_8 : EXT_CSD_BUS_WIDTH_4;  		err = mmc_select_powerclass(card, ext_csd_bits, ext_csd); -		if (err) { -			pr_err("%s: power class selection to bus width %d failed\n", -				mmc_hostname(card->host), 1 << bus_width); -			goto err; -		} +		if (err) +			pr_warning("%s: power class selection to bus width %d" +				   " failed\n", mmc_hostname(card->host), +				   1 << bus_width);  	}  	/* @@ -1147,10 +1151,10 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,  			err = mmc_select_powerclass(card, ext_csd_bits[idx][0],  						    ext_csd);  			if (err) -				pr_err("%s: power class selection to " -				       "bus width %d failed\n", -				       mmc_hostname(card->host), -				       1 << bus_width); +				pr_warning("%s: power class selection to " +					   "bus width %d failed\n", +					   mmc_hostname(card->host), +					   1 << bus_width);  			err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,  					 EXT_CSD_BUS_WIDTH, @@ -1178,10 +1182,10 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,  			err = mmc_select_powerclass(card, ext_csd_bits[idx][1],  						    ext_csd);  			if (err) -				pr_err("%s: power class selection to " -				       "bus width %d ddr %d failed\n", -				       mmc_hostname(card->host), -				       1 << bus_width, ddr); +				pr_warning("%s: power class selection to " +					   "bus width %d ddr %d failed\n", +					   mmc_hostname(card->host), +					   1 << bus_width, ddr);  			err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,  					 EXT_CSD_BUS_WIDTH, diff --git a/drivers/mmc/core/sdio_bus.c b/drivers/mmc/core/sdio_bus.c index 40989e6bb53..236842ec955 100644 --- a/drivers/mmc/core/sdio_bus.c +++ b/drivers/mmc/core/sdio_bus.c @@ -192,9 +192,15 @@ static int sdio_bus_remove(struct device *dev)  	return ret;  } -#ifdef CONFIG_PM_RUNTIME +#ifdef CONFIG_PM + +static int pm_no_operation(struct device *dev) +{ +	return 0; +}  static const struct dev_pm_ops sdio_bus_pm_ops = { +	SET_SYSTEM_SLEEP_PM_OPS(pm_no_operation, pm_no_operation)  	SET_RUNTIME_PM_OPS(  		pm_generic_runtime_suspend,  		pm_generic_runtime_resume, @@ -204,11 +210,11 @@ static const struct dev_pm_ops sdio_bus_pm_ops = {  #define SDIO_PM_OPS_PTR	(&sdio_bus_pm_ops) -#else /* !CONFIG_PM_RUNTIME */ +#else /* !CONFIG_PM */  #define SDIO_PM_OPS_PTR	NULL -#endif /* !CONFIG_PM_RUNTIME */ +#endif /* !CONFIG_PM */  static struct bus_type sdio_bus_type = {  	.name		= "sdio",  |