diff options
Diffstat (limited to 'drivers/mmc/core')
| -rw-r--r-- | drivers/mmc/core/Kconfig | 19 | ||||
| -rw-r--r-- | drivers/mmc/core/Makefile | 3 | ||||
| -rw-r--r-- | drivers/mmc/core/bus.c | 141 | ||||
| -rw-r--r-- | drivers/mmc/core/core.c | 1888 | ||||
| -rw-r--r-- | drivers/mmc/core/core.h | 29 | ||||
| -rw-r--r-- | drivers/mmc/core/debugfs.c | 71 | ||||
| -rw-r--r-- | drivers/mmc/core/host.c | 438 | ||||
| -rw-r--r-- | drivers/mmc/core/host.h | 3 | ||||
| -rw-r--r-- | drivers/mmc/core/mmc.c | 1429 | ||||
| -rw-r--r-- | drivers/mmc/core/mmc_ops.c | 431 | ||||
| -rw-r--r-- | drivers/mmc/core/mmc_ops.h | 4 | ||||
| -rw-r--r-- | drivers/mmc/core/quirks.c | 99 | ||||
| -rw-r--r-- | drivers/mmc/core/sd.c | 712 | ||||
| -rw-r--r-- | drivers/mmc/core/sd.h | 3 | ||||
| -rw-r--r-- | drivers/mmc/core/sd_ops.c | 64 | ||||
| -rw-r--r-- | drivers/mmc/core/sdio.c | 620 | ||||
| -rw-r--r-- | drivers/mmc/core/sdio_bus.c | 111 | ||||
| -rw-r--r-- | drivers/mmc/core/sdio_cis.c | 4 | ||||
| -rw-r--r-- | drivers/mmc/core/sdio_io.c | 19 | ||||
| -rw-r--r-- | drivers/mmc/core/sdio_irq.c | 111 | ||||
| -rw-r--r-- | drivers/mmc/core/sdio_ops.c | 57 | ||||
| -rw-r--r-- | drivers/mmc/core/slot-gpio.c | 355 | 
22 files changed, 5327 insertions, 1284 deletions
diff --git a/drivers/mmc/core/Kconfig b/drivers/mmc/core/Kconfig index bb22ffd76ef..9ebee72d9c3 100644 --- a/drivers/mmc/core/Kconfig +++ b/drivers/mmc/core/Kconfig @@ -2,17 +2,12 @@  # MMC core configuration  # -config MMC_UNSAFE_RESUME -	bool "Assume MMC/SD cards are non-removable (DANGEROUS)" +config MMC_CLKGATE +	bool "MMC host clock gating"  	help -	  If you say Y here, the MMC layer will assume that all cards -	  stayed in their respective slots during the suspend. The -	  normal behaviour is to remove them at suspend and -	  redetecting them at resume. Breaking this assumption will -	  in most cases result in data corruption. +	  This will attempt to aggressively gate the clock to the MMC card. +	  This is done to save power due to gating off the logic and bus +	  noise when the MMC card is not in use. Your host driver has to +	  support handling this in order for it to be of any use. -	  This option is usually just for embedded systems which use -	  a MMC/SD card for rootfs. Most people should say N here. - -	  This option sets a default which can be overridden by the -	  module parameter "removable=0" or "removable=1". +	  If unsure, say N. diff --git a/drivers/mmc/core/Makefile b/drivers/mmc/core/Makefile index 86b47911933..38ed210ce2f 100644 --- a/drivers/mmc/core/Makefile +++ b/drivers/mmc/core/Makefile @@ -6,6 +6,7 @@ obj-$(CONFIG_MMC)		+= mmc_core.o  mmc_core-y			:= core.o bus.o host.o \  				   mmc.o mmc_ops.o sd.o sd_ops.o \  				   sdio.o sdio_ops.o sdio_bus.o \ -				   sdio_cis.o sdio_io.o sdio_irq.o +				   sdio_cis.o sdio_io.o sdio_irq.o \ +				   quirks.o slot-gpio.o  mmc_core-$(CONFIG_DEBUG_FS)	+= debugfs.o diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c index af8dc6a2a31..d2dbf02022b 100644 --- a/drivers/mmc/core/bus.c +++ b/drivers/mmc/core/bus.c @@ -11,9 +11,11 @@   *  MMC card bus driver model   */ +#include <linux/export.h>  #include <linux/device.h>  #include <linux/err.h>  #include <linux/slab.h> +#include <linux/stat.h>  #include <linux/pm_runtime.h>  #include <linux/mmc/card.h> @@ -25,7 +27,7 @@  #define to_mmc_driver(d)	container_of(d, struct mmc_driver, drv) -static ssize_t mmc_type_show(struct device *dev, +static ssize_t type_show(struct device *dev,  	struct device_attribute *attr, char *buf)  {  	struct mmc_card *card = mmc_dev_to_card(dev); @@ -43,11 +45,13 @@ static ssize_t mmc_type_show(struct device *dev,  		return -EFAULT;  	}  } +static DEVICE_ATTR_RO(type); -static struct device_attribute mmc_dev_attrs[] = { -	__ATTR(type, S_IRUGO, mmc_type_show, NULL), -	__ATTR_NULL, +static struct attribute *mmc_dev_attrs[] = { +	&dev_attr_type.attr, +	NULL,  }; +ATTRIBUTE_GROUPS(mmc_dev);  /*   * This currently matches any MMC driver to any MMC card - drivers @@ -120,14 +124,39 @@ static int mmc_bus_remove(struct device *dev)  	return 0;  } -static int mmc_bus_suspend(struct device *dev, pm_message_t state) +static void mmc_bus_shutdown(struct device *dev)  {  	struct mmc_driver *drv = to_mmc_driver(dev->driver);  	struct mmc_card *card = mmc_dev_to_card(dev); -	int ret = 0; +	struct mmc_host *host = card->host; +	int ret; + +	if (dev->driver && drv->shutdown) +		drv->shutdown(card); + +	if (host->bus_ops->shutdown) { +		ret = host->bus_ops->shutdown(host); +		if (ret) +			pr_warn("%s: error %d during shutdown\n", +				mmc_hostname(host), ret); +	} +} + +#ifdef CONFIG_PM_SLEEP +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); +	struct mmc_host *host = card->host; +	int ret; -	if (dev->driver && drv->suspend) -		ret = drv->suspend(card, state); +	if (dev->driver && drv->suspend) { +		ret = drv->suspend(card); +		if (ret) +			return ret; +	} + +	ret = host->bus_ops->suspend(host);  	return ret;  } @@ -135,58 +164,61 @@ static int mmc_bus_resume(struct device *dev)  {  	struct mmc_driver *drv = to_mmc_driver(dev->driver);  	struct mmc_card *card = mmc_dev_to_card(dev); -	int ret = 0; +	struct mmc_host *host = card->host; +	int ret; + +	ret = host->bus_ops->resume(host); +	if (ret) +		pr_warn("%s: error %d during resume (card was removed?)\n", +			mmc_hostname(host), ret);  	if (dev->driver && drv->resume)  		ret = drv->resume(card); +  	return ret;  } +#endif  #ifdef CONFIG_PM_RUNTIME  static int mmc_runtime_suspend(struct device *dev)  {  	struct mmc_card *card = mmc_dev_to_card(dev); +	struct mmc_host *host = card->host; -	return mmc_power_save_host(card->host); +	return host->bus_ops->runtime_suspend(host);  }  static int mmc_runtime_resume(struct device *dev)  {  	struct mmc_card *card = mmc_dev_to_card(dev); +	struct mmc_host *host = card->host; -	return mmc_power_restore_host(card->host); +	return host->bus_ops->runtime_resume(host);  }  static int mmc_runtime_idle(struct device *dev)  { -	return pm_runtime_suspend(dev); +	return 0;  } +#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, +	.dev_groups	= mmc_dev_groups,  	.match		= mmc_bus_match,  	.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, +	.shutdown	= mmc_bus_shutdown, +	.pm		= &mmc_bus_pm_ops,  };  int mmc_register_bus(void) @@ -229,8 +261,7 @@ static void mmc_release_card(struct device *dev)  	sdio_free_common_cis(card); -	if (card->info) -		kfree(card->info); +	kfree(card->info);  	kfree(card);  } @@ -265,6 +296,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); @@ -274,8 +314,12 @@ int mmc_add_card(struct mmc_card *card)  		break;  	case MMC_TYPE_SD:  		type = "SD"; -		if (mmc_card_blockaddr(card)) -			type = "SDHC"; +		if (mmc_card_blockaddr(card)) { +			if (mmc_card_ext_capacity(card)) +				type = "SDXC"; +			else +				type = "SDHC"; +		}  		break;  	case MMC_TYPE_SDIO:  		type = "SDIO"; @@ -284,32 +328,41 @@ int mmc_add_card(struct mmc_card *card)  		type = "SD-combo";  		if (mmc_card_blockaddr(card))  			type = "SDHC-combo"; +		break;  	default:  		type = "?";  		break;  	} +	if (mmc_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)) { -		printk(KERN_INFO "%s: new %s%s%s card on SPI\n", +		pr_info("%s: new %s%s%s card on SPI\n",  			mmc_hostname(card->host), -			mmc_card_highspeed(card) ? "high speed " : "", -			mmc_card_ddr_mode(card) ? "DDR " : "", +			mmc_card_hs(card) ? "high speed " : "", +			mmc_card_ddr52(card) ? "DDR " : "",  			type);  	} else { -		printk(KERN_INFO "%s: new %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_highspeed(card) ? "high speed " : "", -			mmc_card_ddr_mode(card) ? "DDR " : "", -			type, card->rca); +			mmc_card_uhs(card) ? "ultra high speed " : +			(mmc_card_hs(card) ? "high speed " : ""), +			mmc_card_hs400(card) ? "HS400 " : +			(mmc_card_hs200(card) ? "HS200 " : ""), +			mmc_card_ddr52(card) ? "DDR " : "", +			uhs_bus_speed_mode, type, card->rca);  	} -	ret = device_add(&card->dev); -	if (ret) -		return ret; -  #ifdef CONFIG_DEBUG_FS  	mmc_add_card_debugfs(card);  #endif +	mmc_init_context_info(card->host); + +	ret = device_add(&card->dev); +	if (ret) +		return ret;  	mmc_card_set_present(card); @@ -328,10 +381,10 @@ void mmc_remove_card(struct mmc_card *card)  	if (mmc_card_present(card)) {  		if (mmc_host_is_spi(card->host)) { -			printk(KERN_INFO "%s: SPI card removed\n", +			pr_info("%s: SPI card removed\n",  				mmc_hostname(card->host));  		} else { -			printk(KERN_INFO "%s: card %04x removed\n", +			pr_info("%s: card %04x removed\n",  				mmc_hostname(card->host), card->rca);  		}  		device_del(&card->dev); diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 8f86d702e46..7dc0c85fdb6 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -22,11 +22,19 @@  #include <linux/scatterlist.h>  #include <linux/log2.h>  #include <linux/regulator/consumer.h> +#include <linux/pm_runtime.h> +#include <linux/pm_wakeup.h> +#include <linux/suspend.h> +#include <linux/fault-inject.h> +#include <linux/random.h> +#include <linux/slab.h> +#include <linux/of.h>  #include <linux/mmc/card.h>  #include <linux/mmc/host.h>  #include <linux/mmc/mmc.h>  #include <linux/mmc/sd.h> +#include <linux/mmc/slot-gpio.h>  #include "core.h"  #include "bus.h" @@ -37,34 +45,27 @@  #include "sd_ops.h"  #include "sdio_ops.h" +/* If the device is not responding */ +#define MMC_CORE_TIMEOUT_MS	(10 * 60 * 1000) /* 10 minute timeout */ + +/* + * Background operations can take a long time, depending on the housekeeping + * operations the card has to perform. + */ +#define MMC_BKOPS_MAX_TIMEOUT	(4 * 60 * 1000) /* max time to wait in ms */ +  static struct workqueue_struct *workqueue; +static const unsigned freqs[] = { 400000, 300000, 200000, 100000 };  /*   * Enabling software CRCs on the data blocks can be a significant (30%)   * performance cost, and for other reasons may not always be desired.   * So we allow it it to be disabled.   */ -int use_spi_crc = 1; +bool use_spi_crc = 1;  module_param(use_spi_crc, bool, 0);  /* - * We normally treat cards as removed during suspend if they are not - * known to be on a non-removable bus, to avoid the risk of writing - * back data to a different card after resume.  Allow this to be - * overridden if necessary. - */ -#ifdef CONFIG_MMC_UNSAFE_RESUME -int mmc_assume_removable; -#else -int mmc_assume_removable = 1; -#endif -EXPORT_SYMBOL(mmc_assume_removable); -module_param_named(removable, mmc_assume_removable, bool, 0644); -MODULE_PARM_DESC( -	removable, -	"MMC/SD cards are removable and may be removed during suspend"); - -/*   * Internal function. Schedule delayed work in the MMC work queue.   */  static int mmc_schedule_delayed_work(struct delayed_work *work, @@ -81,6 +82,43 @@ static void mmc_flush_scheduled_work(void)  	flush_workqueue(workqueue);  } +#ifdef CONFIG_FAIL_MMC_REQUEST + +/* + * Internal function. Inject random data errors. + * If mmc_data is NULL no errors are injected. + */ +static void mmc_should_fail_request(struct mmc_host *host, +				    struct mmc_request *mrq) +{ +	struct mmc_command *cmd = mrq->cmd; +	struct mmc_data *data = mrq->data; +	static const int data_errors[] = { +		-ETIMEDOUT, +		-EILSEQ, +		-EIO, +	}; + +	if (!data) +		return; + +	if (cmd->error || data->error || +	    !should_fail(&host->fail_mmc_request, data->blksz * data->blocks)) +		return; + +	data->error = data_errors[prandom_u32() % ARRAY_SIZE(data_errors)]; +	data->bytes_xfered = (prandom_u32() % (data->bytes_xfered >> 9)) << 9; +} + +#else /* CONFIG_FAIL_MMC_REQUEST */ + +static inline void mmc_should_fail_request(struct mmc_host *host, +					   struct mmc_request *mrq) +{ +} + +#endif /* CONFIG_FAIL_MMC_REQUEST */ +  /**   *	mmc_request_done - finish processing an MMC request   *	@host: MMC host which completed request @@ -99,14 +137,16 @@ void mmc_request_done(struct mmc_host *host, struct mmc_request *mrq)  			cmd->retries = 0;  	} -	if (err && cmd->retries) { -		pr_debug("%s: req failed (CMD%u): %d, retrying...\n", -			mmc_hostname(host), cmd->opcode, err); - -		cmd->retries--; -		cmd->error = 0; -		host->ops->request(host, mrq); +	if (err && cmd->retries && !mmc_card_removed(host->card)) { +		/* +		 * Request starter must handle retries - see +		 * mmc_wait_for_req_done(). +		 */ +		if (mrq->done) +			mrq->done(mrq);  	} else { +		mmc_should_fail_request(host, mrq); +  		led_trigger_event(host->led, LED_OFF);  		pr_debug("%s: req done (CMD%u): %d: %08x %08x %08x %08x\n", @@ -130,6 +170,8 @@ void mmc_request_done(struct mmc_host *host, struct mmc_request *mrq)  		if (mrq->done)  			mrq->done(mrq); + +		mmc_host_clk_release(host);  	}  } @@ -143,6 +185,12 @@ mmc_start_request(struct mmc_host *host, struct mmc_request *mrq)  	struct scatterlist *sg;  #endif +	if (mrq->sbc) { +		pr_debug("<%s: starting CMD%u arg %08x flags %08x>\n", +			 mmc_hostname(host), mrq->sbc->opcode, +			 mrq->sbc->arg, mrq->sbc->flags); +	} +  	pr_debug("%s: starting CMD%u arg %08x flags %08x\n",  		 mmc_hostname(host), mrq->cmd->opcode,  		 mrq->cmd->arg, mrq->cmd->flags); @@ -164,8 +212,6 @@ mmc_start_request(struct mmc_host *host, struct mmc_request *mrq)  	WARN_ON(!host->claimed); -	led_trigger_event(host->led, LED_FULL); -  	mrq->cmd->error = 0;  	mrq->cmd->mrq = mrq;  	if (mrq->data) { @@ -190,14 +236,333 @@ mmc_start_request(struct mmc_host *host, struct mmc_request *mrq)  			mrq->stop->mrq = mrq;  		}  	} +	mmc_host_clk_hold(host); +	led_trigger_event(host->led, LED_FULL);  	host->ops->request(host, mrq);  } +/** + *	mmc_start_bkops - start BKOPS for supported cards + *	@card: MMC card to start BKOPS + *	@form_exception: A flag to indicate if this function was + *			 called due to an exception raised by the card + * + *	Start background operations whenever requested. + *	When the urgent BKOPS bit is set in a R1 command response + *	then background operations should be started immediately. +*/ +void mmc_start_bkops(struct mmc_card *card, bool from_exception) +{ +	int err; +	int timeout; +	bool use_busy_signal; + +	BUG_ON(!card); + +	if (!card->ext_csd.bkops_en || mmc_card_doing_bkops(card)) +		return; + +	err = mmc_read_bkops_status(card); +	if (err) { +		pr_err("%s: Failed to read bkops status: %d\n", +		       mmc_hostname(card->host), err); +		return; +	} + +	if (!card->ext_csd.raw_bkops_status) +		return; + +	if (card->ext_csd.raw_bkops_status < EXT_CSD_BKOPS_LEVEL_2 && +	    from_exception) +		return; + +	mmc_claim_host(card->host); +	if (card->ext_csd.raw_bkops_status >= EXT_CSD_BKOPS_LEVEL_2) { +		timeout = MMC_BKOPS_MAX_TIMEOUT; +		use_busy_signal = true; +	} else { +		timeout = 0; +		use_busy_signal = false; +	} + +	err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, +			EXT_CSD_BKOPS_START, 1, timeout, +			use_busy_signal, true, false); +	if (err) { +		pr_warn("%s: Error %d starting bkops\n", +			mmc_hostname(card->host), err); +		goto out; +	} + +	/* +	 * For urgent bkops status (LEVEL_2 and more) +	 * bkops executed synchronously, otherwise +	 * the operation is in progress +	 */ +	if (!use_busy_signal) +		mmc_card_set_doing_bkops(card); +out: +	mmc_release_host(card->host); +} +EXPORT_SYMBOL(mmc_start_bkops); + +/* + * mmc_wait_data_done() - done callback for data request + * @mrq: done data request + * + * Wakes up mmc context, passed as a callback to host controller driver + */ +static void mmc_wait_data_done(struct mmc_request *mrq) +{ +	mrq->host->context_info.is_done_rcv = true; +	wake_up_interruptible(&mrq->host->context_info.wait); +} +  static void mmc_wait_done(struct mmc_request *mrq)  { -	complete(mrq->done_data); +	complete(&mrq->completion);  } +/* + *__mmc_start_data_req() - starts data request + * @host: MMC host to start the request + * @mrq: data request to start + * + * Sets the done callback to be called when request is completed by the card. + * Starts data mmc request execution + */ +static int __mmc_start_data_req(struct mmc_host *host, struct mmc_request *mrq) +{ +	mrq->done = mmc_wait_data_done; +	mrq->host = host; +	if (mmc_card_removed(host->card)) { +		mrq->cmd->error = -ENOMEDIUM; +		mmc_wait_data_done(mrq); +		return -ENOMEDIUM; +	} +	mmc_start_request(host, mrq); + +	return 0; +} + +static int __mmc_start_req(struct mmc_host *host, struct mmc_request *mrq) +{ +	init_completion(&mrq->completion); +	mrq->done = mmc_wait_done; +	if (mmc_card_removed(host->card)) { +		mrq->cmd->error = -ENOMEDIUM; +		complete(&mrq->completion); +		return -ENOMEDIUM; +	} +	mmc_start_request(host, mrq); +	return 0; +} + +/* + * mmc_wait_for_data_req_done() - wait for request completed + * @host: MMC host to prepare the command. + * @mrq: MMC request to wait for + * + * Blocks MMC context till host controller will ack end of data request + * execution or new request notification arrives from the block layer. + * Handles command retries. + * + * Returns enum mmc_blk_status after checking errors. + */ +static int mmc_wait_for_data_req_done(struct mmc_host *host, +				      struct mmc_request *mrq, +				      struct mmc_async_req *next_req) +{ +	struct mmc_command *cmd; +	struct mmc_context_info *context_info = &host->context_info; +	int err; +	unsigned long flags; + +	while (1) { +		wait_event_interruptible(context_info->wait, +				(context_info->is_done_rcv || +				 context_info->is_new_req)); +		spin_lock_irqsave(&context_info->lock, flags); +		context_info->is_waiting_last_req = false; +		spin_unlock_irqrestore(&context_info->lock, flags); +		if (context_info->is_done_rcv) { +			context_info->is_done_rcv = false; +			context_info->is_new_req = false; +			cmd = mrq->cmd; + +			if (!cmd->error || !cmd->retries || +			    mmc_card_removed(host->card)) { +				err = host->areq->err_check(host->card, +							    host->areq); +				break; /* return err */ +			} else { +				pr_info("%s: req failed (CMD%u): %d, retrying...\n", +					mmc_hostname(host), +					cmd->opcode, cmd->error); +				cmd->retries--; +				cmd->error = 0; +				host->ops->request(host, mrq); +				continue; /* wait for done/new event again */ +			} +		} else if (context_info->is_new_req) { +			context_info->is_new_req = false; +			if (!next_req) { +				err = MMC_BLK_NEW_REQUEST; +				break; /* return err */ +			} +		} +	} +	return err; +} + +static void mmc_wait_for_req_done(struct mmc_host *host, +				  struct mmc_request *mrq) +{ +	struct mmc_command *cmd; + +	while (1) { +		wait_for_completion(&mrq->completion); + +		cmd = mrq->cmd; + +		/* +		 * If host has timed out waiting for the sanitize +		 * to complete, card might be still in programming state +		 * so let's try to bring the card out of programming +		 * state. +		 */ +		if (cmd->sanitize_busy && cmd->error == -ETIMEDOUT) { +			if (!mmc_interrupt_hpi(host->card)) { +				pr_warning("%s: %s: Interrupted sanitize\n", +					   mmc_hostname(host), __func__); +				cmd->error = 0; +				break; +			} else { +				pr_err("%s: %s: Failed to interrupt sanitize\n", +				       mmc_hostname(host), __func__); +			} +		} +		if (!cmd->error || !cmd->retries || +		    mmc_card_removed(host->card)) +			break; + +		pr_debug("%s: req failed (CMD%u): %d, retrying...\n", +			 mmc_hostname(host), cmd->opcode, cmd->error); +		cmd->retries--; +		cmd->error = 0; +		host->ops->request(host, mrq); +	} +} + +/** + *	mmc_pre_req - Prepare for a new request + *	@host: MMC host to prepare command + *	@mrq: MMC request to prepare for + *	@is_first_req: true if there is no previous started request + *                     that may run in parellel to this call, otherwise false + * + *	mmc_pre_req() is called in prior to mmc_start_req() to let + *	host prepare for the new request. Preparation of a request may be + *	performed while another request is running on the host. + */ +static void mmc_pre_req(struct mmc_host *host, struct mmc_request *mrq, +		 bool is_first_req) +{ +	if (host->ops->pre_req) { +		mmc_host_clk_hold(host); +		host->ops->pre_req(host, mrq, is_first_req); +		mmc_host_clk_release(host); +	} +} + +/** + *	mmc_post_req - Post process a completed request + *	@host: MMC host to post process command + *	@mrq: MMC request to post process for + *	@err: Error, if non zero, clean up any resources made in pre_req + * + *	Let the host post process a completed request. Post processing of + *	a request may be performed while another reuqest is running. + */ +static void mmc_post_req(struct mmc_host *host, struct mmc_request *mrq, +			 int err) +{ +	if (host->ops->post_req) { +		mmc_host_clk_hold(host); +		host->ops->post_req(host, mrq, err); +		mmc_host_clk_release(host); +	} +} + +/** + *	mmc_start_req - start a non-blocking request + *	@host: MMC host to start command + *	@areq: async request to start + *	@error: out parameter returns 0 for success, otherwise non zero + * + *	Start a new MMC custom command request for a host. + *	If there is on ongoing async request wait for completion + *	of that request and start the new one and return. + *	Does not wait for the new request to complete. + * + *      Returns the completed request, NULL in case of none completed. + *	Wait for the an ongoing request (previoulsy started) to complete and + *	return the completed request. If there is no ongoing request, NULL + *	is returned without waiting. NULL is not an error condition. + */ +struct mmc_async_req *mmc_start_req(struct mmc_host *host, +				    struct mmc_async_req *areq, int *error) +{ +	int err = 0; +	int start_err = 0; +	struct mmc_async_req *data = host->areq; + +	/* Prepare a new request */ +	if (areq) +		mmc_pre_req(host, areq->mrq, !host->areq); + +	if (host->areq) { +		err = mmc_wait_for_data_req_done(host, host->areq->mrq,	areq); +		if (err == MMC_BLK_NEW_REQUEST) { +			if (error) +				*error = err; +			/* +			 * The previous request was not completed, +			 * nothing to return +			 */ +			return NULL; +		} +		/* +		 * Check BKOPS urgency for each R1 response +		 */ +		if (host->card && mmc_card_mmc(host->card) && +		    ((mmc_resp_type(host->areq->mrq->cmd) == MMC_RSP_R1) || +		     (mmc_resp_type(host->areq->mrq->cmd) == MMC_RSP_R1B)) && +		    (host->areq->mrq->cmd->resp[0] & R1_EXCEPTION_EVENT)) +			mmc_start_bkops(host->card, true); +	} + +	if (!err && areq) +		start_err = __mmc_start_data_req(host, areq->mrq); + +	if (host->areq) +		mmc_post_req(host, host->areq->mrq, 0); + +	 /* Cancel a prepared request if it was not started. */ +	if ((err || start_err) && areq) +		mmc_post_req(host, areq->mrq, -EINVAL); + +	if (err) +		host->areq = NULL; +	else +		host->areq = areq; + +	if (error) +		*error = err; +	return data; +} +EXPORT_SYMBOL(mmc_start_req); +  /**   *	mmc_wait_for_req - start a request and wait for completion   *	@host: MMC host to start command @@ -209,17 +574,77 @@ static void mmc_wait_done(struct mmc_request *mrq)   */  void mmc_wait_for_req(struct mmc_host *host, struct mmc_request *mrq)  { -	DECLARE_COMPLETION_ONSTACK(complete); +	__mmc_start_req(host, mrq); +	mmc_wait_for_req_done(host, mrq); +} +EXPORT_SYMBOL(mmc_wait_for_req); -	mrq->done_data = &complete; -	mrq->done = mmc_wait_done; +/** + *	mmc_interrupt_hpi - Issue for High priority Interrupt + *	@card: the MMC card associated with the HPI transfer + * + *	Issued High Priority Interrupt, and check for card status + *	until out-of prg-state. + */ +int mmc_interrupt_hpi(struct mmc_card *card) +{ +	int err; +	u32 status; +	unsigned long prg_wait; -	mmc_start_request(host, mrq); +	BUG_ON(!card); -	wait_for_completion(&complete); -} +	if (!card->ext_csd.hpi_en) { +		pr_info("%s: HPI enable bit unset\n", mmc_hostname(card->host)); +		return 1; +	} -EXPORT_SYMBOL(mmc_wait_for_req); +	mmc_claim_host(card->host); +	err = mmc_send_status(card, &status); +	if (err) { +		pr_err("%s: Get card status fail\n", mmc_hostname(card->host)); +		goto out; +	} + +	switch (R1_CURRENT_STATE(status)) { +	case R1_STATE_IDLE: +	case R1_STATE_READY: +	case R1_STATE_STBY: +	case R1_STATE_TRAN: +		/* +		 * In idle and transfer states, HPI is not needed and the caller +		 * can issue the next intended command immediately +		 */ +		goto out; +	case R1_STATE_PRG: +		break; +	default: +		/* In all other states, it's illegal to issue HPI */ +		pr_debug("%s: HPI cannot be sent. Card state=%d\n", +			mmc_hostname(card->host), R1_CURRENT_STATE(status)); +		err = -EINVAL; +		goto out; +	} + +	err = mmc_send_hpi_cmd(card, &status); +	if (err) +		goto out; + +	prg_wait = jiffies + msecs_to_jiffies(card->ext_csd.out_of_int_time); +	do { +		err = mmc_send_status(card, &status); + +		if (!err && R1_CURRENT_STATE(status) == R1_STATE_TRAN) +			break; +		if (time_after(jiffies, prg_wait)) +			err = -ETIMEDOUT; +	} while (!err); + +out: +	mmc_release_host(card->host); +	return err; +} +EXPORT_SYMBOL(mmc_interrupt_hpi);  /**   *	mmc_wait_for_cmd - start a command and wait for completion @@ -233,12 +658,10 @@ EXPORT_SYMBOL(mmc_wait_for_req);   */  int mmc_wait_for_cmd(struct mmc_host *host, struct mmc_command *cmd, int retries)  { -	struct mmc_request mrq; +	struct mmc_request mrq = {NULL};  	WARN_ON(!host->claimed); -	memset(&mrq, 0, sizeof(struct mmc_request)); -  	memset(cmd->resp, 0, sizeof(cmd->resp));  	cmd->retries = retries; @@ -253,6 +676,64 @@ int mmc_wait_for_cmd(struct mmc_host *host, struct mmc_command *cmd, int retries  EXPORT_SYMBOL(mmc_wait_for_cmd);  /** + *	mmc_stop_bkops - stop ongoing BKOPS + *	@card: MMC card to check BKOPS + * + *	Send HPI command to stop ongoing background operations to + *	allow rapid servicing of foreground operations, e.g. read/ + *	writes. Wait until the card comes out of the programming state + *	to avoid errors in servicing read/write requests. + */ +int mmc_stop_bkops(struct mmc_card *card) +{ +	int err = 0; + +	BUG_ON(!card); +	err = mmc_interrupt_hpi(card); + +	/* +	 * If err is EINVAL, we can't issue an HPI. +	 * It should complete the BKOPS. +	 */ +	if (!err || (err == -EINVAL)) { +		mmc_card_clr_doing_bkops(card); +		err = 0; +	} + +	return err; +} +EXPORT_SYMBOL(mmc_stop_bkops); + +int mmc_read_bkops_status(struct mmc_card *card) +{ +	int err; +	u8 *ext_csd; + +	/* +	 * In future work, we should consider storing the entire ext_csd. +	 */ +	ext_csd = kmalloc(512, GFP_KERNEL); +	if (!ext_csd) { +		pr_err("%s: could not allocate buffer to receive the ext_csd.\n", +		       mmc_hostname(card->host)); +		return -ENOMEM; +	} + +	mmc_claim_host(card->host); +	err = mmc_send_ext_csd(card, ext_csd); +	mmc_release_host(card->host); +	if (err) +		goto out; + +	card->ext_csd.raw_bkops_status = ext_csd[EXT_CSD_BKOPS_STATUS]; +	card->ext_csd.raw_exception_status = ext_csd[EXT_CSD_EXP_EVENTS_STATUS]; +out: +	kfree(ext_csd); +	return err; +} +EXPORT_SYMBOL(mmc_read_bkops_status); + +/**   *	mmc_set_data_timeout - set the timeout for a data command   *	@data: data phase for command   *	@card: the MMC card associated with the data transfer @@ -295,15 +776,20 @@ void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card)  		unsigned int timeout_us, limit_us;  		timeout_us = data->timeout_ns / 1000; -		timeout_us += data->timeout_clks * 1000 / -			(card->host->ios.clock / 1000); +		if (mmc_host_clk_rate(card->host)) +			timeout_us += data->timeout_clks * 1000 / +				(mmc_host_clk_rate(card->host) / 1000);  		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; @@ -314,7 +800,23 @@ void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card)  			data->timeout_ns = limit_us * 1000;  			data->timeout_clks = 0;  		} + +		/* assign limit value if invalid */ +		if (timeout_us == 0) +			data->timeout_ns = limit_us * 1000; +	} + +	/* +	 * Some cards require longer data read timeout than indicated in CSD. +	 * Address this by setting the read timeout to a "reasonably high" +	 * value. For the cards tested, 300ms has proven enough. If necessary, +	 * this value can be increased if other problematic cards require this. +	 */ +	if (mmc_card_long_read_time(card) && data->flags & MMC_DATA_READ) { +		data->timeout_ns = 300000000; +		data->timeout_clks = 0;  	} +  	/*  	 * Some cards need very high timeouts if driven in SPI mode.  	 * The worst observed timeout was 900ms after writing a @@ -361,101 +863,6 @@ unsigned int mmc_align_data_size(struct mmc_card *card, unsigned int sz)  EXPORT_SYMBOL(mmc_align_data_size);  /** - *	mmc_host_enable - enable a host. - *	@host: mmc host to enable - * - *	Hosts that support power saving can use the 'enable' and 'disable' - *	methods to exit and enter power saving states. For more information - *	see comments for struct mmc_host_ops. - */ -int mmc_host_enable(struct mmc_host *host) -{ -	if (!(host->caps & MMC_CAP_DISABLE)) -		return 0; - -	if (host->en_dis_recurs) -		return 0; - -	if (host->nesting_cnt++) -		return 0; - -	cancel_delayed_work_sync(&host->disable); - -	if (host->enabled) -		return 0; - -	if (host->ops->enable) { -		int err; - -		host->en_dis_recurs = 1; -		err = host->ops->enable(host); -		host->en_dis_recurs = 0; - -		if (err) { -			pr_debug("%s: enable error %d\n", -				 mmc_hostname(host), err); -			return err; -		} -	} -	host->enabled = 1; -	return 0; -} -EXPORT_SYMBOL(mmc_host_enable); - -static int mmc_host_do_disable(struct mmc_host *host, int lazy) -{ -	if (host->ops->disable) { -		int err; - -		host->en_dis_recurs = 1; -		err = host->ops->disable(host, lazy); -		host->en_dis_recurs = 0; - -		if (err < 0) { -			pr_debug("%s: disable error %d\n", -				 mmc_hostname(host), err); -			return err; -		} -		if (err > 0) { -			unsigned long delay = msecs_to_jiffies(err); - -			mmc_schedule_delayed_work(&host->disable, delay); -		} -	} -	host->enabled = 0; -	return 0; -} - -/** - *	mmc_host_disable - disable a host. - *	@host: mmc host to disable - * - *	Hosts that support power saving can use the 'enable' and 'disable' - *	methods to exit and enter power saving states. For more information - *	see comments for struct mmc_host_ops. - */ -int mmc_host_disable(struct mmc_host *host) -{ -	int err; - -	if (!(host->caps & MMC_CAP_DISABLE)) -		return 0; - -	if (host->en_dis_recurs) -		return 0; - -	if (--host->nesting_cnt) -		return 0; - -	if (!host->enabled) -		return 0; - -	err = mmc_host_do_disable(host, 0); -	return err; -} -EXPORT_SYMBOL(mmc_host_disable); - -/**   *	__mmc_claim_host - exclusively claim a host   *	@host: mmc host to claim   *	@abort: whether or not the operation should be aborted @@ -493,39 +900,28 @@ int __mmc_claim_host(struct mmc_host *host, atomic_t *abort)  		wake_up(&host->wq);  	spin_unlock_irqrestore(&host->lock, flags);  	remove_wait_queue(&host->wq, &wait); -	if (!stop) -		mmc_host_enable(host); +	if (host->ops->enable && !stop && host->claim_cnt == 1) +		host->ops->enable(host);  	return stop;  }  EXPORT_SYMBOL(__mmc_claim_host);  /** - *	mmc_try_claim_host - try exclusively to claim a host - *	@host: mmc host to claim + *	mmc_release_host - release a host + *	@host: mmc host to release   * - *	Returns %1 if the host is claimed, %0 otherwise. + *	Release a MMC host, allowing others to claim the host + *	for their operations.   */ -int mmc_try_claim_host(struct mmc_host *host) +void mmc_release_host(struct mmc_host *host)  { -	int claimed_host = 0;  	unsigned long flags; -	spin_lock_irqsave(&host->lock, flags); -	if (!host->claimed || host->claimer == current) { -		host->claimed = 1; -		host->claimer = current; -		host->claim_cnt += 1; -		claimed_host = 1; -	} -	spin_unlock_irqrestore(&host->lock, flags); -	return claimed_host; -} -EXPORT_SYMBOL(mmc_try_claim_host); +	WARN_ON(!host->claimed); -static void mmc_do_release_host(struct mmc_host *host) -{ -	unsigned long flags; +	if (host->ops->disable && host->claim_cnt == 1) +		host->ops->disable(host);  	spin_lock_irqsave(&host->lock, flags);  	if (--host->claim_cnt) { @@ -538,67 +934,30 @@ static void mmc_do_release_host(struct mmc_host *host)  		wake_up(&host->wq);  	}  } +EXPORT_SYMBOL(mmc_release_host); -void mmc_host_deeper_disable(struct work_struct *work) -{ -	struct mmc_host *host = -		container_of(work, struct mmc_host, disable.work); - -	/* If the host is claimed then we do not want to disable it anymore */ -	if (!mmc_try_claim_host(host)) -		return; -	mmc_host_do_disable(host, 1); -	mmc_do_release_host(host); -} - -/** - *	mmc_host_lazy_disable - lazily disable a host. - *	@host: mmc host to disable - * - *	Hosts that support power saving can use the 'enable' and 'disable' - *	methods to exit and enter power saving states. For more information - *	see comments for struct mmc_host_ops. +/* + * This is a helper function, which fetches a runtime pm reference for the + * card device and also claims the host.   */ -int mmc_host_lazy_disable(struct mmc_host *host) +void mmc_get_card(struct mmc_card *card)  { -	if (!(host->caps & MMC_CAP_DISABLE)) -		return 0; - -	if (host->en_dis_recurs) -		return 0; - -	if (--host->nesting_cnt) -		return 0; - -	if (!host->enabled) -		return 0; - -	if (host->disable_delay) { -		mmc_schedule_delayed_work(&host->disable, -				msecs_to_jiffies(host->disable_delay)); -		return 0; -	} else -		return mmc_host_do_disable(host, 1); +	pm_runtime_get_sync(&card->dev); +	mmc_claim_host(card->host);  } -EXPORT_SYMBOL(mmc_host_lazy_disable); +EXPORT_SYMBOL(mmc_get_card); -/** - *	mmc_release_host - release a host - *	@host: mmc host to release - * - *	Release a MMC host, allowing others to claim the host - *	for their operations. +/* + * This is a helper function, which releases the host and drops the runtime + * pm reference for the card device.   */ -void mmc_release_host(struct mmc_host *host) +void mmc_put_card(struct mmc_card *card)  { -	WARN_ON(!host->claimed); - -	mmc_host_lazy_disable(host); - -	mmc_do_release_host(host); +	mmc_release_host(card->host); +	pm_runtime_mark_last_busy(&card->dev); +	pm_runtime_put_autosuspend(&card->dev);  } - -EXPORT_SYMBOL(mmc_release_host); +EXPORT_SYMBOL(mmc_put_card);  /*   * Internal function that does the actual ios call to the host driver, @@ -614,6 +973,8 @@ static inline void mmc_set_ios(struct mmc_host *host)  		 ios->power_mode, ios->chip_select, ios->vdd,  		 ios->bus_width, ios->timing); +	if (ios->clock > 0) +		mmc_set_ungated(host);  	host->ops->set_ios(host, ios);  } @@ -622,15 +983,17 @@ static inline void mmc_set_ios(struct mmc_host *host)   */  void mmc_set_chip_select(struct mmc_host *host, int mode)  { +	mmc_host_clk_hold(host);  	host->ios.chip_select = mode;  	mmc_set_ios(host); +	mmc_host_clk_release(host);  }  /*   * Sets the host clock to the highest possible frequency that   * is below "hz".   */ -void mmc_set_clock(struct mmc_host *host, unsigned int hz) +static void __mmc_set_clock(struct mmc_host *host, unsigned int hz)  {  	WARN_ON(hz < host->f_min); @@ -641,24 +1004,77 @@ void mmc_set_clock(struct mmc_host *host, unsigned int hz)  	mmc_set_ios(host);  } +void mmc_set_clock(struct mmc_host *host, unsigned int hz) +{ +	mmc_host_clk_hold(host); +	__mmc_set_clock(host, hz); +	mmc_host_clk_release(host); +} + +#ifdef CONFIG_MMC_CLKGATE  /* - * Change the bus mode (open drain/push-pull) of a host. + * This gates the clock by setting it to 0 Hz.   */ -void mmc_set_bus_mode(struct mmc_host *host, unsigned int mode) +void mmc_gate_clock(struct mmc_host *host)  { -	host->ios.bus_mode = mode; +	unsigned long flags; + +	spin_lock_irqsave(&host->clk_lock, flags); +	host->clk_old = host->ios.clock; +	host->ios.clock = 0; +	host->clk_gated = true; +	spin_unlock_irqrestore(&host->clk_lock, flags);  	mmc_set_ios(host);  }  /* - * Change data bus width and DDR mode of a host. + * This restores the clock from gating by using the cached + * clock value.   */ -void mmc_set_bus_width_ddr(struct mmc_host *host, unsigned int width, -			   unsigned int ddr) +void mmc_ungate_clock(struct mmc_host *host)  { -	host->ios.bus_width = width; -	host->ios.ddr = ddr; +	/* +	 * We should previously have gated the clock, so the clock shall +	 * be 0 here! The clock may however be 0 during initialization, +	 * when some request operations are performed before setting +	 * the frequency. When ungate is requested in that situation +	 * we just ignore the call. +	 */ +	if (host->clk_old) { +		BUG_ON(host->ios.clock); +		/* This call will also set host->clk_gated to false */ +		__mmc_set_clock(host, host->clk_old); +	} +} + +void mmc_set_ungated(struct mmc_host *host) +{ +	unsigned long flags; + +	/* +	 * We've been given a new frequency while the clock is gated, +	 * so make sure we regard this as ungating it. +	 */ +	spin_lock_irqsave(&host->clk_lock, flags); +	host->clk_gated = false; +	spin_unlock_irqrestore(&host->clk_lock, flags); +} + +#else +void mmc_set_ungated(struct mmc_host *host) +{ +} +#endif + +/* + * Change the bus mode (open drain/push-pull) of a host. + */ +void mmc_set_bus_mode(struct mmc_host *host, unsigned int mode) +{ +	mmc_host_clk_hold(host); +	host->ios.bus_mode = mode;  	mmc_set_ios(host); +	mmc_host_clk_release(host);  }  /* @@ -666,7 +1082,10 @@ void mmc_set_bus_width_ddr(struct mmc_host *host, unsigned int width,   */  void mmc_set_bus_width(struct mmc_host *host, unsigned int width)  { -	mmc_set_bus_width_ddr(host, width, MMC_SDR_MODE); +	mmc_host_clk_hold(host); +	host->ios.bus_width = width; +	mmc_set_ios(host); +	mmc_host_clk_release(host);  }  /** @@ -743,6 +1162,49 @@ u32 mmc_vddrange_to_ocrmask(int vdd_min, int vdd_max)  }  EXPORT_SYMBOL(mmc_vddrange_to_ocrmask); +#ifdef CONFIG_OF + +/** + * mmc_of_parse_voltage - return mask of supported voltages + * @np: The device node need to be parsed. + * @mask: mask of voltages available for MMC/SD/SDIO + * + * 1. Return zero on success. + * 2. Return negative errno: voltage-range is invalid. + */ +int mmc_of_parse_voltage(struct device_node *np, u32 *mask) +{ +	const u32 *voltage_ranges; +	int num_ranges, i; + +	voltage_ranges = of_get_property(np, "voltage-ranges", &num_ranges); +	num_ranges = num_ranges / sizeof(*voltage_ranges) / 2; +	if (!voltage_ranges || !num_ranges) { +		pr_info("%s: voltage-ranges unspecified\n", np->full_name); +		return -EINVAL; +	} + +	for (i = 0; i < num_ranges; i++) { +		const int j = i * 2; +		u32 ocr_mask; + +		ocr_mask = mmc_vddrange_to_ocrmask( +				be32_to_cpu(voltage_ranges[j]), +				be32_to_cpu(voltage_ranges[j + 1])); +		if (!ocr_mask) { +			pr_err("%s: voltage-range #%d is invalid\n", +				np->full_name, i); +			return -EINVAL; +		} +		*mask |= ocr_mask; +	} + +	return 0; +} +EXPORT_SYMBOL(mmc_of_parse_voltage); + +#endif /* CONFIG_OF */ +  #ifdef CONFIG_REGULATOR  /** @@ -778,7 +1240,7 @@ int mmc_regulator_get_ocrmask(struct regulator *supply)  	return result;  } -EXPORT_SYMBOL(mmc_regulator_get_ocrmask); +EXPORT_SYMBOL_GPL(mmc_regulator_get_ocrmask);  /**   * mmc_regulator_set_ocr - set regulator to match host->ios voltage @@ -803,7 +1265,8 @@ int mmc_regulator_set_ocr(struct mmc_host *mmc,  		int		tmp;  		int		voltage; -		/* REVISIT mmc_vddrange_to_ocrmask() may have set some +		/* +		 * REVISIT mmc_vddrange_to_ocrmask() may have set some  		 * bits this regulator doesn't quite support ... don't  		 * be too picky, most cards and regulators are OK with  		 * a 0.1V range goof (it's a small error percentage). @@ -817,10 +1280,15 @@ int mmc_regulator_set_ocr(struct mmc_host *mmc,  			max_uV = min_uV + 100 * 1000;  		} -		/* avoid needless changes to this voltage; the regulator -		 * might not allow this operation +		/* +		 * If we're using a fixed/static regulator, don't call +		 * regulator_set_voltage; it would fail.  		 */  		voltage = regulator_get_voltage(supply); + +		if (!regulator_can_change_voltage(supply)) +			min_uV = max_uV = voltage; +  		if (voltage < 0)  			result = voltage;  		else if (voltage < min_uV || voltage > max_uV) @@ -844,10 +1312,40 @@ int mmc_regulator_set_ocr(struct mmc_host *mmc,  			"could not set regulator OCR (%d)\n", result);  	return result;  } -EXPORT_SYMBOL(mmc_regulator_set_ocr); +EXPORT_SYMBOL_GPL(mmc_regulator_set_ocr);  #endif /* CONFIG_REGULATOR */ +int mmc_regulator_get_supply(struct mmc_host *mmc) +{ +	struct device *dev = mmc_dev(mmc); +	int ret; + +	mmc->supply.vmmc = devm_regulator_get_optional(dev, "vmmc"); +	mmc->supply.vqmmc = devm_regulator_get_optional(dev, "vqmmc"); + +	if (IS_ERR(mmc->supply.vmmc)) { +		if (PTR_ERR(mmc->supply.vmmc) == -EPROBE_DEFER) +			return -EPROBE_DEFER; +		dev_info(dev, "No vmmc regulator found\n"); +	} else { +		ret = mmc_regulator_get_ocrmask(mmc->supply.vmmc); +		if (ret > 0) +			mmc->ocr_avail = ret; +		else +			dev_warn(dev, "Failed getting OCR mask: %d\n", ret); +	} + +	if (IS_ERR(mmc->supply.vqmmc)) { +		if (PTR_ERR(mmc->supply.vqmmc) == -EPROBE_DEFER) +			return -EPROBE_DEFER; +		dev_info(dev, "No vqmmc regulator found\n"); +	} + +	return 0; +} +EXPORT_SYMBOL_GPL(mmc_regulator_get_supply); +  /*   * Mask off any voltages we don't support and select   * the lowest voltage @@ -856,32 +1354,165 @@ u32 mmc_select_voltage(struct mmc_host *host, u32 ocr)  {  	int bit; -	ocr &= host->ocr_avail; +	/* +	 * Sanity check the voltages that the card claims to +	 * support. +	 */ +	if (ocr & 0x7F) { +		dev_warn(mmc_dev(host), +		"card claims to support voltages below defined range\n"); +		ocr &= ~0x7F; +	} -	bit = ffs(ocr); -	if (bit) { -		bit -= 1; +	ocr &= host->ocr_avail; +	if (!ocr) { +		dev_warn(mmc_dev(host), "no support for card's volts\n"); +		return 0; +	} +	if (host->caps2 & MMC_CAP2_FULL_PWR_CYCLE) { +		bit = ffs(ocr) - 1;  		ocr &= 3 << bit; - -		host->ios.vdd = bit; -		mmc_set_ios(host); +		mmc_power_cycle(host, ocr);  	} else { -		pr_warning("%s: host doesn't support card's voltages\n", -				mmc_hostname(host)); -		ocr = 0; +		bit = fls(ocr) - 1; +		ocr &= 3 << bit; +		if (bit != host->ios.vdd) +			dev_warn(mmc_dev(host), "exceeding card's volts\n");  	}  	return ocr;  } +int __mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage) +{ +	int err = 0; +	int old_signal_voltage = host->ios.signal_voltage; + +	host->ios.signal_voltage = signal_voltage; +	if (host->ops->start_signal_voltage_switch) { +		mmc_host_clk_hold(host); +		err = host->ops->start_signal_voltage_switch(host, &host->ios); +		mmc_host_clk_release(host); +	} + +	if (err) +		host->ios.signal_voltage = old_signal_voltage; + +	return err; + +} + +int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage, u32 ocr) +{ +	struct mmc_command cmd = {0}; +	int err = 0; +	u32 clock; + +	BUG_ON(!host); + +	/* +	 * Send CMD11 only if the request is to switch the card to +	 * 1.8V signalling. +	 */ +	if (signal_voltage == MMC_SIGNAL_VOLTAGE_330) +		return __mmc_set_signal_voltage(host, signal_voltage); + +	/* +	 * If we cannot switch voltages, return failure so the caller +	 * can continue without UHS mode +	 */ +	if (!host->ops->start_signal_voltage_switch) +		return -EPERM; +	if (!host->ops->card_busy) +		pr_warning("%s: cannot verify signal voltage switch\n", +				mmc_hostname(host)); + +	cmd.opcode = SD_SWITCH_VOLTAGE; +	cmd.arg = 0; +	cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; + +	err = mmc_wait_for_cmd(host, &cmd, 0); +	if (err) +		return err; + +	if (!mmc_host_is_spi(host) && (cmd.resp[0] & R1_ERROR)) +		return -EIO; + +	mmc_host_clk_hold(host); +	/* +	 * The card should drive cmd and dat[0:3] low immediately +	 * after the response of cmd11, but wait 1 ms to be sure +	 */ +	mmc_delay(1); +	if (host->ops->card_busy && !host->ops->card_busy(host)) { +		err = -EAGAIN; +		goto power_cycle; +	} +	/* +	 * During a signal voltage level switch, the clock must be gated +	 * for 5 ms according to the SD spec +	 */ +	clock = host->ios.clock; +	host->ios.clock = 0; +	mmc_set_ios(host); + +	if (__mmc_set_signal_voltage(host, signal_voltage)) { +		/* +		 * Voltages may not have been switched, but we've already +		 * sent CMD11, so a power cycle is required anyway +		 */ +		err = -EAGAIN; +		goto power_cycle; +	} + +	/* Keep clock gated for at least 5 ms */ +	mmc_delay(5); +	host->ios.clock = clock; +	mmc_set_ios(host); + +	/* Wait for at least 1 ms according to spec */ +	mmc_delay(1); + +	/* +	 * Failure to switch is indicated by the card holding +	 * dat[0:3] low +	 */ +	if (host->ops->card_busy && host->ops->card_busy(host)) +		err = -EAGAIN; + +power_cycle: +	if (err) { +		pr_debug("%s: Signal voltage switch failed, " +			"power cycling card\n", mmc_hostname(host)); +		mmc_power_cycle(host, ocr); +	} + +	mmc_host_clk_release(host); + +	return err; +} +  /*   * Select timing parameters for host.   */  void mmc_set_timing(struct mmc_host *host, unsigned int timing)  { +	mmc_host_clk_hold(host);  	host->ios.timing = timing;  	mmc_set_ios(host); +	mmc_host_clk_release(host); +} + +/* + * Select appropriate driver type for host. + */ +void mmc_set_driver_type(struct mmc_host *host, unsigned int drv_type) +{ +	mmc_host_clk_hold(host); +	host->ios.drv_type = drv_type; +	mmc_set_ios(host); +	mmc_host_clk_release(host);  }  /* @@ -895,29 +1526,32 @@ void mmc_set_timing(struct mmc_host *host, unsigned int timing)   * If a host does all the power sequencing itself, ignore the   * initial MMC_POWER_UP stage.   */ -static void mmc_power_up(struct mmc_host *host) +void mmc_power_up(struct mmc_host *host, u32 ocr)  { -	int bit; +	if (host->ios.power_mode == MMC_POWER_ON) +		return; -	/* If ocr is set, we use it */ -	if (host->ocr) -		bit = ffs(host->ocr) - 1; -	else -		bit = fls(host->ocr_avail) - 1; +	mmc_host_clk_hold(host); -	host->ios.vdd = bit; -	if (mmc_host_is_spi(host)) { +	host->ios.vdd = fls(ocr) - 1; +	if (mmc_host_is_spi(host))  		host->ios.chip_select = MMC_CS_HIGH; -		host->ios.bus_mode = MMC_BUSMODE_PUSHPULL; -	} else { +	else  		host->ios.chip_select = MMC_CS_DONTCARE; -		host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN; -	} +	host->ios.bus_mode = MMC_BUSMODE_PUSHPULL;  	host->ios.power_mode = MMC_POWER_UP;  	host->ios.bus_width = MMC_BUS_WIDTH_1;  	host->ios.timing = MMC_TIMING_LEGACY;  	mmc_set_ios(host); +	/* Try to set signal voltage to 3.3V but fall back to 1.8v or 1.2v */ +	if (__mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_330) == 0) +		dev_dbg(mmc_dev(host), "Initial signal voltage of 3.3v\n"); +	else if (__mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180) == 0) +		dev_dbg(mmc_dev(host), "Initial signal voltage of 1.8v\n"); +	else if (__mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_120) == 0) +		dev_dbg(mmc_dev(host), "Initial signal voltage of 1.2v\n"); +  	/*  	 * This delay should be sufficient to allow the power supply  	 * to reach the minimum voltage. @@ -934,12 +1568,20 @@ static void mmc_power_up(struct mmc_host *host)  	 * time required to reach a stable voltage.  	 */  	mmc_delay(10); + +	mmc_host_clk_release(host);  } -static void mmc_power_off(struct mmc_host *host) +void mmc_power_off(struct mmc_host *host)  { +	if (host->ios.power_mode == MMC_POWER_OFF) +		return; + +	mmc_host_clk_hold(host); +  	host->ios.clock = 0;  	host->ios.vdd = 0; +  	if (!mmc_host_is_spi(host)) {  		host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN;  		host->ios.chip_select = MMC_CS_DONTCARE; @@ -948,6 +1590,23 @@ static void mmc_power_off(struct mmc_host *host)  	host->ios.bus_width = MMC_BUS_WIDTH_1;  	host->ios.timing = MMC_TIMING_LEGACY;  	mmc_set_ios(host); + +	/* +	 * Some configurations, such as the 802.11 SDIO card in the OLPC +	 * XO-1.5, require a short delay after poweroff before the card +	 * can be successfully turned on again. +	 */ +	mmc_delay(1); + +	mmc_host_clk_release(host); +} + +void mmc_power_cycle(struct mmc_host *host, u32 ocr) +{ +	mmc_power_off(host); +	/* Wait at least 1 ms according to SD spec */ +	mmc_delay(1); +	mmc_power_up(host, ocr);  }  /* @@ -1015,8 +1674,7 @@ void mmc_attach_bus(struct mmc_host *host, const struct mmc_bus_ops *ops)  }  /* - * Remove the current bus handler from a host. Assumes that there are - * no interesting cards left, so the bus is powered down. + * Remove the current bus handler from a host.   */  void mmc_detach_bus(struct mmc_host *host)  { @@ -1033,11 +1691,31 @@ void mmc_detach_bus(struct mmc_host *host)  	spin_unlock_irqrestore(&host->lock, flags); -	mmc_power_off(host); -  	mmc_bus_put(host);  } +static void _mmc_detect_change(struct mmc_host *host, unsigned long delay, +				bool cd_irq) +{ +#ifdef CONFIG_MMC_DEBUG +	unsigned long flags; +	spin_lock_irqsave(&host->lock, flags); +	WARN_ON(host->removed); +	spin_unlock_irqrestore(&host->lock, flags); +#endif + +	/* +	 * If the device is configured as wakeup, we prevent a new sleep for +	 * 5 s to give provision for user space to consume the event. +	 */ +	if (cd_irq && !(host->caps & MMC_CAP_NEEDS_POLL) && +		device_can_wakeup(mmc_dev(host))) +		pm_wakeup_event(mmc_dev(host), 5000); + +	host->detect_change = 1; +	mmc_schedule_delayed_work(&host->detect, delay); +} +  /**   *	mmc_detect_change - process change of state on a MMC socket   *	@host: host which changed state. @@ -1050,16 +1728,8 @@ void mmc_detach_bus(struct mmc_host *host)   */  void mmc_detect_change(struct mmc_host *host, unsigned long delay)  { -#ifdef CONFIG_MMC_DEBUG -	unsigned long flags; -	spin_lock_irqsave(&host->lock, flags); -	WARN_ON(host->removed); -	spin_unlock_irqrestore(&host->lock, flags); -#endif - -	mmc_schedule_delayed_work(&host->detect, delay); +	_mmc_detect_change(host, delay, true);  } -  EXPORT_SYMBOL(mmc_detect_change);  void mmc_init_erase(struct mmc_card *card) @@ -1111,13 +1781,15 @@ void mmc_init_erase(struct mmc_card *card)  	}  } -static void mmc_set_mmc_erase_timeout(struct mmc_card *card, -				      struct mmc_command *cmd, -				      unsigned int arg, unsigned int qty) +static unsigned int mmc_mmc_erase_timeout(struct mmc_card *card, +				          unsigned int arg, unsigned int qty)  {  	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; @@ -1141,7 +1813,7 @@ static void mmc_set_mmc_erase_timeout(struct mmc_card *card,  		 */  		timeout_clks <<= 1;  		timeout_us += (timeout_clks * 1000) / -			      (card->host->ios.clock / 1000); +			      (mmc_host_clk_rate(card->host) / 1000);  		erase_timeout = timeout_us / 1000; @@ -1170,45 +1842,50 @@ static void mmc_set_mmc_erase_timeout(struct mmc_card *card,  	if (mmc_host_is_spi(card->host) && erase_timeout < 1000)  		erase_timeout = 1000; -	cmd->erase_timeout = erase_timeout; +	return erase_timeout;  } -static void mmc_set_sd_erase_timeout(struct mmc_card *card, -				     struct mmc_command *cmd, unsigned int arg, -				     unsigned int qty) +static unsigned int mmc_sd_erase_timeout(struct mmc_card *card, +					 unsigned int arg, +					 unsigned int qty)  { +	unsigned int erase_timeout; +  	if (card->ssr.erase_timeout) {  		/* Erase timeout specified in SD Status Register (SSR) */ -		cmd->erase_timeout = card->ssr.erase_timeout * qty + -				     card->ssr.erase_offset; +		erase_timeout = card->ssr.erase_timeout * qty + +				card->ssr.erase_offset;  	} else {  		/*  		 * Erase timeout not specified in SD Status Register (SSR) so  		 * use 250ms per write block.  		 */ -		cmd->erase_timeout = 250 * qty; +		erase_timeout = 250 * qty;  	}  	/* Must not be less than 1 second */ -	if (cmd->erase_timeout < 1000) -		cmd->erase_timeout = 1000; +	if (erase_timeout < 1000) +		erase_timeout = 1000; + +	return erase_timeout;  } -static void mmc_set_erase_timeout(struct mmc_card *card, -				  struct mmc_command *cmd, unsigned int arg, -				  unsigned int qty) +static unsigned int mmc_erase_timeout(struct mmc_card *card, +				      unsigned int arg, +				      unsigned int qty)  {  	if (mmc_card_sd(card)) -		mmc_set_sd_erase_timeout(card, cmd, arg, qty); +		return mmc_sd_erase_timeout(card, arg, qty);  	else -		mmc_set_mmc_erase_timeout(card, cmd, arg, qty); +		return mmc_mmc_erase_timeout(card, arg, qty);  }  static int mmc_do_erase(struct mmc_card *card, unsigned int from,  			unsigned int to, unsigned int arg)  { -	struct mmc_command cmd; +	struct mmc_command cmd = {0};  	unsigned int qty = 0; +	unsigned long timeout;  	int err;  	/* @@ -1241,7 +1918,6 @@ static int mmc_do_erase(struct mmc_card *card, unsigned int from,  		to <<= 9;  	} -	memset(&cmd, 0, sizeof(struct mmc_command));  	if (mmc_card_sd(card))  		cmd.opcode = SD_ERASE_WR_BLK_START;  	else @@ -1250,9 +1926,9 @@ static int mmc_do_erase(struct mmc_card *card, unsigned int from,  	cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC;  	err = mmc_wait_for_cmd(card->host, &cmd, 0);  	if (err) { -		printk(KERN_ERR "mmc_erase: group start error %d, " +		pr_err("mmc_erase: group start error %d, "  		       "status %#x\n", err, cmd.resp[0]); -		err = -EINVAL; +		err = -EIO;  		goto out;  	} @@ -1265,9 +1941,9 @@ static int mmc_do_erase(struct mmc_card *card, unsigned int from,  	cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC;  	err = mmc_wait_for_cmd(card->host, &cmd, 0);  	if (err) { -		printk(KERN_ERR "mmc_erase: group end error %d, status %#x\n", +		pr_err("mmc_erase: group end error %d, status %#x\n",  		       err, cmd.resp[0]); -		err = -EINVAL; +		err = -EIO;  		goto out;  	} @@ -1275,10 +1951,10 @@ static int mmc_do_erase(struct mmc_card *card, unsigned int from,  	cmd.opcode = MMC_ERASE;  	cmd.arg = arg;  	cmd.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC; -	mmc_set_erase_timeout(card, &cmd, arg, qty); +	cmd.busy_timeout = mmc_erase_timeout(card, arg, qty);  	err = mmc_wait_for_cmd(card->host, &cmd, 0);  	if (err) { -		printk(KERN_ERR "mmc_erase: erase error %d, status %#x\n", +		pr_err("mmc_erase: erase error %d, status %#x\n",  		       err, cmd.resp[0]);  		err = -EIO;  		goto out; @@ -1287,6 +1963,7 @@ static int mmc_do_erase(struct mmc_card *card, unsigned int from,  	if (mmc_host_is_spi(card->host))  		goto out; +	timeout = jiffies + msecs_to_jiffies(MMC_CORE_TIMEOUT_MS);  	do {  		memset(&cmd, 0, sizeof(struct mmc_command));  		cmd.opcode = MMC_SEND_STATUS; @@ -1295,13 +1972,24 @@ static int mmc_do_erase(struct mmc_card *card, unsigned int from,  		/* Do not retry else we can't see errors */  		err = mmc_wait_for_cmd(card->host, &cmd, 0);  		if (err || (cmd.resp[0] & 0xFDF92000)) { -			printk(KERN_ERR "error %d requesting status %#x\n", +			pr_err("error %d requesting status %#x\n",  				err, cmd.resp[0]);  			err = -EIO;  			goto out;  		} + +		/* Timeout if the device never becomes ready for data and +		 * never leaves the program state. +		 */ +		if (time_after(jiffies, timeout)) { +			pr_err("%s: Card stuck in programming state! %s\n", +				mmc_hostname(card->host), __func__); +			err =  -EIO; +			goto out; +		} +  	} while (!(cmd.resp[0] & R1_READY_FOR_DATA) || -		 R1_CURRENT_STATE(cmd.resp[0]) == 7); +		 (R1_CURRENT_STATE(cmd.resp[0]) == R1_STATE_PRG));  out:  	return err;  } @@ -1390,6 +2078,28 @@ int mmc_can_trim(struct mmc_card *card)  }  EXPORT_SYMBOL(mmc_can_trim); +int mmc_can_discard(struct mmc_card *card) +{ +	/* +	 * As there's no way to detect the discard support bit at v4.5 +	 * use the s/w feature support filed. +	 */ +	if (card->ext_csd.feature_support & MMC_DISCARD_FEATURE) +		return 1; +	return 0; +} +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; +} +EXPORT_SYMBOL(mmc_can_sanitize); +  int mmc_can_secure_erase_trim(struct mmc_card *card)  {  	if (card->ext_csd.sec_feature_support & EXT_CSD_SEC_ER_EN) @@ -1409,14 +2119,89 @@ int mmc_erase_group_aligned(struct mmc_card *card, unsigned int from,  }  EXPORT_SYMBOL(mmc_erase_group_aligned); +static unsigned int mmc_do_calc_max_discard(struct mmc_card *card, +					    unsigned int arg) +{ +	struct mmc_host *host = card->host; +	unsigned int max_discard, x, y, qty = 0, max_qty, timeout; +	unsigned int last_timeout = 0; + +	if (card->erase_shift) +		max_qty = UINT_MAX >> card->erase_shift; +	else if (mmc_card_sd(card)) +		max_qty = UINT_MAX; +	else +		max_qty = UINT_MAX / card->erase_size; + +	/* Find the largest qty with an OK timeout */ +	do { +		y = 0; +		for (x = 1; x && x <= max_qty && max_qty - x >= qty; x <<= 1) { +			timeout = mmc_erase_timeout(card, arg, qty + x); +			if (timeout > host->max_busy_timeout) +				break; +			if (timeout < last_timeout) +				break; +			last_timeout = timeout; +			y = x; +		} +		qty += y; +	} while (y); + +	if (!qty) +		return 0; + +	if (qty == 1) +		return 1; + +	/* Convert qty to sectors */ +	if (card->erase_shift) +		max_discard = --qty << card->erase_shift; +	else if (mmc_card_sd(card)) +		max_discard = qty; +	else +		max_discard = --qty * card->erase_size; + +	return max_discard; +} + +unsigned int mmc_calc_max_discard(struct mmc_card *card) +{ +	struct mmc_host *host = card->host; +	unsigned int max_discard, max_trim; + +	if (!host->max_busy_timeout) +		return UINT_MAX; + +	/* +	 * Without erase_group_def set, MMC erase timeout depends on clock +	 * frequence which can change.  In that case, the best choice is +	 * just the preferred erase size. +	 */ +	if (mmc_card_mmc(card) && !(card->ext_csd.erase_group_def & 1)) +		return card->pref_erase; + +	max_discard = mmc_do_calc_max_discard(card, MMC_ERASE_ARG); +	if (mmc_can_trim(card)) { +		max_trim = mmc_do_calc_max_discard(card, MMC_TRIM_ARG); +		if (max_trim < max_discard) +			max_discard = max_trim; +	} else if (max_discard < card->erase_size) { +		max_discard = 0; +	} +	pr_debug("%s: calculated max. discard sectors %u for timeout %u ms\n", +		 mmc_hostname(host), max_discard, host->max_busy_timeout); +	return max_discard; +} +EXPORT_SYMBOL(mmc_calc_max_discard); +  int mmc_set_blocklen(struct mmc_card *card, unsigned int blocklen)  { -	struct mmc_command cmd; +	struct mmc_command cmd = {0}; -	if (mmc_card_blockaddr(card) || mmc_card_ddr_mode(card)) +	if (mmc_card_blockaddr(card) || mmc_card_ddr52(card))  		return 0; -	memset(&cmd, 0, sizeof(struct mmc_command));  	cmd.opcode = MMC_SET_BLOCKLEN;  	cmd.arg = blocklen;  	cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC; @@ -1424,35 +2209,245 @@ int mmc_set_blocklen(struct mmc_card *card, unsigned int blocklen)  }  EXPORT_SYMBOL(mmc_set_blocklen); +int mmc_set_blockcount(struct mmc_card *card, unsigned int blockcount, +			bool is_rel_write) +{ +	struct mmc_command cmd = {0}; + +	cmd.opcode = MMC_SET_BLOCK_COUNT; +	cmd.arg = blockcount & 0x0000FFFF; +	if (is_rel_write) +		cmd.arg |= 1 << 31; +	cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC; +	return mmc_wait_for_cmd(card->host, &cmd, 5); +} +EXPORT_SYMBOL(mmc_set_blockcount); + +static void mmc_hw_reset_for_init(struct mmc_host *host) +{ +	if (!(host->caps & MMC_CAP_HW_RESET) || !host->ops->hw_reset) +		return; +	mmc_host_clk_hold(host); +	host->ops->hw_reset(host); +	mmc_host_clk_release(host); +} + +int mmc_can_reset(struct mmc_card *card) +{ +	u8 rst_n_function; + +	if (!mmc_card_mmc(card)) +		return 0; +	rst_n_function = card->ext_csd.rst_n_function; +	if ((rst_n_function & EXT_CSD_RST_N_EN_MASK) != EXT_CSD_RST_N_ENABLED) +		return 0; +	return 1; +} +EXPORT_SYMBOL(mmc_can_reset); + +static int mmc_do_hw_reset(struct mmc_host *host, int check) +{ +	struct mmc_card *card = host->card; + +	if (!(host->caps & MMC_CAP_HW_RESET) || !host->ops->hw_reset) +		return -EOPNOTSUPP; + +	if (!card) +		return -EINVAL; + +	if (!mmc_can_reset(card)) +		return -EOPNOTSUPP; + +	mmc_host_clk_hold(host); +	mmc_set_clock(host, host->f_init); + +	host->ops->hw_reset(host); + +	/* If the reset has happened, then a status command will fail */ +	if (check) { +		struct mmc_command cmd = {0}; +		int err; + +		cmd.opcode = MMC_SEND_STATUS; +		if (!mmc_host_is_spi(card->host)) +			cmd.arg = card->rca << 16; +		cmd.flags = MMC_RSP_SPI_R2 | MMC_RSP_R1 | MMC_CMD_AC; +		err = mmc_wait_for_cmd(card->host, &cmd, 0); +		if (!err) { +			mmc_host_clk_release(host); +			return -ENOSYS; +		} +	} + +	if (mmc_host_is_spi(host)) { +		host->ios.chip_select = MMC_CS_HIGH; +		host->ios.bus_mode = MMC_BUSMODE_PUSHPULL; +	} else { +		host->ios.chip_select = MMC_CS_DONTCARE; +		host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN; +	} +	host->ios.bus_width = MMC_BUS_WIDTH_1; +	host->ios.timing = MMC_TIMING_LEGACY; +	mmc_set_ios(host); + +	mmc_host_clk_release(host); + +	return host->bus_ops->power_restore(host); +} + +int mmc_hw_reset(struct mmc_host *host) +{ +	return mmc_do_hw_reset(host, 0); +} +EXPORT_SYMBOL(mmc_hw_reset); + +int mmc_hw_reset_check(struct mmc_host *host) +{ +	return mmc_do_hw_reset(host, 1); +} +EXPORT_SYMBOL(mmc_hw_reset_check); + +static int mmc_rescan_try_freq(struct mmc_host *host, unsigned freq) +{ +	host->f_init = freq; + +#ifdef CONFIG_MMC_DEBUG +	pr_info("%s: %s: trying to init card at %u Hz\n", +		mmc_hostname(host), __func__, host->f_init); +#endif +	mmc_power_up(host, host->ocr_avail); + +	/* +	 * Some eMMCs (with VCCQ always on) may not be reset after power up, so +	 * do a hardware reset if possible. +	 */ +	mmc_hw_reset_for_init(host); + +	/* +	 * sdio_reset sends CMD52 to reset card.  Since we do not know +	 * if the card is being re-initialized, just send it.  CMD52 +	 * should be ignored by SD/eMMC cards. +	 */ +	sdio_reset(host); +	mmc_go_idle(host); + +	mmc_send_if_cond(host, host->ocr_avail); + +	/* Order's important: probe SDIO, then SD, then MMC */ +	if (!mmc_attach_sdio(host)) +		return 0; +	if (!mmc_attach_sd(host)) +		return 0; +	if (!mmc_attach_mmc(host)) +		return 0; + +	mmc_power_off(host); +	return -EIO; +} + +int _mmc_detect_card_removed(struct mmc_host *host) +{ +	int ret; + +	if (host->caps & MMC_CAP_NONREMOVABLE) +		return 0; + +	if (!host->card || mmc_card_removed(host->card)) +		return 1; + +	ret = host->bus_ops->alive(host); + +	/* +	 * Card detect status and alive check may be out of sync if card is +	 * removed slowly, when card detect switch changes while card/slot +	 * pads are still contacted in hardware (refer to "SD Card Mechanical +	 * Addendum, Appendix C: Card Detection Switch"). So reschedule a +	 * detect work 200ms later for this case. +	 */ +	if (!ret && host->ops->get_cd && !host->ops->get_cd(host)) { +		mmc_detect_change(host, msecs_to_jiffies(200)); +		pr_debug("%s: card removed too slowly\n", mmc_hostname(host)); +	} + +	if (ret) { +		mmc_card_set_removed(host->card); +		pr_debug("%s: card remove detected\n", mmc_hostname(host)); +	} + +	return ret; +} + +int mmc_detect_card_removed(struct mmc_host *host) +{ +	struct mmc_card *card = host->card; +	int ret; + +	WARN_ON(!host->claimed); + +	if (!card) +		return 1; + +	ret = mmc_card_removed(card); +	/* +	 * The card will be considered unchanged unless we have been asked to +	 * detect a change or host requires polling to provide card detection. +	 */ +	if (!host->detect_change && !(host->caps & MMC_CAP_NEEDS_POLL)) +		return ret; + +	host->detect_change = 0; +	if (!ret) { +		ret = _mmc_detect_card_removed(host); +		if (ret && (host->caps & MMC_CAP_NEEDS_POLL)) { +			/* +			 * Schedule a detect work as soon as possible to let a +			 * rescan handle the card removal. +			 */ +			cancel_delayed_work(&host->detect); +			_mmc_detect_change(host, 0, false); +		} +	} + +	return ret; +} +EXPORT_SYMBOL(mmc_detect_card_removed); +  void mmc_rescan(struct work_struct *work)  {  	struct mmc_host *host =  		container_of(work, struct mmc_host, detect.work); -	u32 ocr; -	int err; -	unsigned long flags;  	int i; -	const unsigned freqs[] = { 400000, 300000, 200000, 100000 }; - -	spin_lock_irqsave(&host->lock, flags); -	if (host->rescan_disable) { -		spin_unlock_irqrestore(&host->lock, flags); -		return; +	if (host->trigger_card_event && host->ops->card_event) { +		host->ops->card_event(host); +		host->trigger_card_event = false;  	} -	spin_unlock_irqrestore(&host->lock, flags); +	if (host->rescan_disable) +		return; +	/* If there is a non-removable card registered, only scan once */ +	if ((host->caps & MMC_CAP_NONREMOVABLE) && host->rescan_entered) +		return; +	host->rescan_entered = 1;  	mmc_bus_get(host); -	/* if there is a card registered, check whether it is still present */ -	if ((host->bus_ops != NULL) && host->bus_ops->detect && !host->bus_dead) +	/* +	 * if there is a _removable_ card registered, check whether it is +	 * still present +	 */ +	if (host->bus_ops && !host->bus_dead +	    && !(host->caps & MMC_CAP_NONREMOVABLE))  		host->bus_ops->detect(host); -	mmc_bus_put(host); - +	host->detect_change = 0; +	/* +	 * Let mmc_bus_put() free the bus/bus_ops if we've found that +	 * the card is no longer present. +	 */ +	mmc_bus_put(host);  	mmc_bus_get(host);  	/* if there still is a card present, stop here */ @@ -1461,91 +2456,44 @@ void mmc_rescan(struct work_struct *work)  		goto out;  	} -	/* detect a newly inserted card */ -  	/*  	 * Only we can add a new handler, so it's safe to  	 * release the lock here.  	 */  	mmc_bus_put(host); -	if (host->ops->get_cd && host->ops->get_cd(host) == 0) +	if (!(host->caps & MMC_CAP_NONREMOVABLE) && host->ops->get_cd && +			host->ops->get_cd(host) == 0) { +		mmc_claim_host(host); +		mmc_power_off(host); +		mmc_release_host(host);  		goto out; +	} +	mmc_claim_host(host);  	for (i = 0; i < ARRAY_SIZE(freqs); i++) { -		mmc_claim_host(host); - -		if (freqs[i] >= host->f_min) -			host->f_init = freqs[i]; -		else if (!i || freqs[i-1] > host->f_min) -			host->f_init = host->f_min; -		else { -			mmc_release_host(host); -			goto out; -		} -#ifdef CONFIG_MMC_DEBUG -		pr_info("%s: %s: trying to init card at %u Hz\n", -			mmc_hostname(host), __func__, host->f_init); -#endif -		mmc_power_up(host); -		sdio_reset(host); -		mmc_go_idle(host); - -		mmc_send_if_cond(host, host->ocr_avail); - -		/* -		 * First we search for SDIO... -		 */ -		err = mmc_send_io_op_cond(host, 0, &ocr); -		if (!err) { -			if (mmc_attach_sdio(host, ocr)) { -				mmc_claim_host(host); -				/* -				 * Try SDMEM (but not MMC) even if SDIO -				 * is broken. -				 */ -				if (mmc_send_app_op_cond(host, 0, &ocr)) -					goto out_fail; - -				if (mmc_attach_sd(host, ocr)) -					mmc_power_off(host); -			} -			goto out; -		} - -		/* -		 * ...then normal SD... -		 */ -		err = mmc_send_app_op_cond(host, 0, &ocr); -		if (!err) { -			if (mmc_attach_sd(host, ocr)) -				mmc_power_off(host); -			goto out; -		} - -		/* -		 * ...and finally MMC. -		 */ -		err = mmc_send_op_cond(host, 0, &ocr); -		if (!err) { -			if (mmc_attach_mmc(host, ocr)) -				mmc_power_off(host); -			goto out; -		} - -out_fail: -		mmc_release_host(host); -		mmc_power_off(host); +		if (!mmc_rescan_try_freq(host, max(freqs[i], host->f_min))) +			break; +		if (freqs[i] <= host->f_min) +			break;  	} -out: +	mmc_release_host(host); + + out:  	if (host->caps & MMC_CAP_NEEDS_POLL)  		mmc_schedule_delayed_work(&host->detect, HZ);  }  void mmc_start_host(struct mmc_host *host)  { -	mmc_power_off(host); -	mmc_detect_change(host, 0); +	host->f_init = max(freqs[0], host->f_min); +	host->rescan_disable = 0; +	if (host->caps2 & MMC_CAP2_NO_PRESCAN_POWERUP) +		mmc_power_off(host); +	else +		mmc_power_up(host, host->ocr_avail); +	mmc_gpiod_request_cd_irq(host); +	_mmc_detect_change(host, 0, false);  }  void mmc_stop_host(struct mmc_host *host) @@ -1556,10 +2504,11 @@ void mmc_stop_host(struct mmc_host *host)  	host->removed = 1;  	spin_unlock_irqrestore(&host->lock, flags);  #endif +	if (host->slot.cd_irq >= 0) +		disable_irq(host->slot.cd_irq); -	if (host->caps & MMC_CAP_DISABLE) -		cancel_delayed_work(&host->disable); -	cancel_delayed_work(&host->detect); +	host->rescan_disable = 1; +	cancel_delayed_work_sync(&host->detect);  	mmc_flush_scheduled_work();  	/* clear pm flags now and let card drivers set them as needed */ @@ -1567,11 +2516,11 @@ void mmc_stop_host(struct mmc_host *host)  	mmc_bus_get(host);  	if (host->bus_ops && !host->bus_dead) { -		if (host->bus_ops->remove) -			host->bus_ops->remove(host); - +		/* Calling bus_ops->remove() with a claimed host can deadlock */ +		host->bus_ops->remove(host);  		mmc_claim_host(host);  		mmc_detach_bus(host); +		mmc_power_off(host);  		mmc_release_host(host);  		mmc_bus_put(host);  		return; @@ -1587,9 +2536,13 @@ int mmc_power_save_host(struct mmc_host *host)  {  	int ret = 0; +#ifdef CONFIG_MMC_DEBUG +	pr_info("%s: %s: powering down\n", mmc_hostname(host), __func__); +#endif +  	mmc_bus_get(host); -	if (!host->bus_ops || host->bus_dead || !host->bus_ops->power_restore) { +	if (!host->bus_ops || host->bus_dead) {  		mmc_bus_put(host);  		return -EINVAL;  	} @@ -1609,14 +2562,18 @@ int mmc_power_restore_host(struct mmc_host *host)  {  	int ret; +#ifdef CONFIG_MMC_DEBUG +	pr_info("%s: %s: powering up\n", mmc_hostname(host), __func__); +#endif +  	mmc_bus_get(host); -	if (!host->bus_ops || host->bus_dead || !host->bus_ops->power_restore) { +	if (!host->bus_ops || host->bus_dead) {  		mmc_bus_put(host);  		return -EINVAL;  	} -	mmc_power_up(host); +	mmc_power_up(host, host->card->ocr);  	ret = host->bus_ops->power_restore(host);  	mmc_bus_put(host); @@ -1625,117 +2582,28 @@ int mmc_power_restore_host(struct mmc_host *host)  }  EXPORT_SYMBOL(mmc_power_restore_host); -int mmc_card_awake(struct mmc_host *host) -{ -	int err = -ENOSYS; - -	mmc_bus_get(host); - -	if (host->bus_ops && !host->bus_dead && host->bus_ops->awake) -		err = host->bus_ops->awake(host); - -	mmc_bus_put(host); - -	return err; -} -EXPORT_SYMBOL(mmc_card_awake); - -int mmc_card_sleep(struct mmc_host *host) -{ -	int err = -ENOSYS; - -	mmc_bus_get(host); - -	if (host->bus_ops && !host->bus_dead && host->bus_ops->awake) -		err = host->bus_ops->sleep(host); - -	mmc_bus_put(host); - -	return err; -} -EXPORT_SYMBOL(mmc_card_sleep); - -int mmc_card_can_sleep(struct mmc_host *host) -{ -	struct mmc_card *card = host->card; - -	if (card && mmc_card_mmc(card) && card->ext_csd.rev >= 3) -		return 1; -	return 0; -} -EXPORT_SYMBOL(mmc_card_can_sleep); - -#ifdef CONFIG_PM - -/** - *	mmc_suspend_host - suspend a host - *	@host: mmc host +/* + * Flush the cache to the non-volatile storage.   */ -int mmc_suspend_host(struct mmc_host *host) +int mmc_flush_cache(struct mmc_card *card)  {  	int err = 0; -	if (host->caps & MMC_CAP_DISABLE) -		cancel_delayed_work(&host->disable); -	cancel_delayed_work(&host->detect); -	mmc_flush_scheduled_work(); - -	mmc_bus_get(host); -	if (host->bus_ops && !host->bus_dead) { -		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. -			 */ -			if (host->bus_ops->remove) -				host->bus_ops->remove(host); -			mmc_claim_host(host); -			mmc_detach_bus(host); -			mmc_release_host(host); -			host->pm_flags = 0; -			err = 0; -		} +	if (mmc_card_mmc(card) && +			(card->ext_csd.cache_size > 0) && +			(card->ext_csd.cache_ctrl & 1)) { +		err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, +				EXT_CSD_FLUSH_CACHE, 1, 0); +		if (err) +			pr_err("%s: cache flush error %d\n", +					mmc_hostname(card->host), err);  	} -	mmc_bus_put(host); - -	if (!err && !(host->pm_flags & MMC_PM_KEEP_POWER)) -		mmc_power_off(host);  	return err;  } +EXPORT_SYMBOL(mmc_flush_cache); -EXPORT_SYMBOL(mmc_suspend_host); - -/** - *	mmc_resume_host - resume a previously suspended host - *	@host: mmc host - */ -int mmc_resume_host(struct mmc_host *host) -{ -	int err = 0; - -	mmc_bus_get(host); -	if (host->bus_ops && !host->bus_dead) { -		if (!(host->pm_flags & MMC_PM_KEEP_POWER)) { -			mmc_power_up(host); -			mmc_select_voltage(host, host->ocr); -		} -		BUG_ON(!host->bus_ops->resume); -		err = host->bus_ops->resume(host); -		if (err) { -			printk(KERN_WARNING "%s: error %d during resume " -					    "(card was removed?)\n", -					    mmc_hostname(host), err); -			err = 0; -		} -	} -	mmc_bus_put(host); - -	return err; -} -EXPORT_SYMBOL(mmc_resume_host); +#ifdef CONFIG_PM  /* Do the card removal on suspend if card is assumed removeable   * Do that in pm notifier while userspace isn't yet frozen, so we will be able @@ -1747,37 +2615,42 @@ int mmc_pm_notify(struct notifier_block *notify_block,  	struct mmc_host *host = container_of(  		notify_block, struct mmc_host, pm_notify);  	unsigned long flags; - +	int err = 0;  	switch (mode) {  	case PM_HIBERNATION_PREPARE:  	case PM_SUSPEND_PREPARE: -  		spin_lock_irqsave(&host->lock, flags);  		host->rescan_disable = 1;  		spin_unlock_irqrestore(&host->lock, flags);  		cancel_delayed_work_sync(&host->detect); -		if (!host->bus_ops || host->bus_ops->suspend) +		if (!host->bus_ops)  			break; -		mmc_claim_host(host); - -		if (host->bus_ops->remove) -			host->bus_ops->remove(host); +		/* Validate prerequisites for suspend */ +		if (host->bus_ops->pre_suspend) +			err = host->bus_ops->pre_suspend(host); +		if (!err) +			break; +		/* Calling bus_ops->remove() with a claimed host can deadlock */ +		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;  		break;  	case PM_POST_SUSPEND:  	case PM_POST_HIBERNATION: +	case PM_POST_RESTORE:  		spin_lock_irqsave(&host->lock, flags);  		host->rescan_disable = 0;  		spin_unlock_irqrestore(&host->lock, flags); -		mmc_detect_change(host, 0); +		_mmc_detect_change(host, 0, false);  	} @@ -1785,11 +2658,28 @@ int mmc_pm_notify(struct notifier_block *notify_block,  }  #endif +/** + * mmc_init_context_info() - init synchronization context + * @host: mmc host + * + * Init struct context_info needed to implement asynchronous + * request mechanism, used by mmc core, host driver and mmc requests + * supplier. + */ +void mmc_init_context_info(struct mmc_host *host) +{ +	spin_lock_init(&host->context_info.lock); +	host->context_info.is_new_req = false; +	host->context_info.is_done_rcv = false; +	host->context_info.is_waiting_last_req = false; +	init_waitqueue_head(&host->context_info.wait); +} +  static int __init mmc_init(void)  {  	int ret; -	workqueue = create_singlethread_workqueue("kmmcd"); +	workqueue = alloc_ordered_workqueue("kmmcd", 0);  	if (!workqueue)  		return -ENOMEM; diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h index 77240cd11bc..443a584660f 100644 --- a/drivers/mmc/core/core.h +++ b/drivers/mmc/core/core.h @@ -16,14 +16,17 @@  #define MMC_CMD_RETRIES        3  struct mmc_bus_ops { -	int (*awake)(struct mmc_host *); -	int (*sleep)(struct mmc_host *);  	void (*remove)(struct mmc_host *);  	void (*detect)(struct mmc_host *); +	int (*pre_suspend)(struct mmc_host *);  	int (*suspend)(struct mmc_host *);  	int (*resume)(struct mmc_host *); +	int (*runtime_suspend)(struct mmc_host *); +	int (*runtime_resume)(struct mmc_host *);  	int (*power_save)(struct mmc_host *);  	int (*power_restore)(struct mmc_host *); +	int (*alive)(struct mmc_host *); +	int (*shutdown)(struct mmc_host *);  };  void mmc_attach_bus(struct mmc_host *host, const struct mmc_bus_ops *ops); @@ -33,12 +36,19 @@ void mmc_init_erase(struct mmc_card *card);  void mmc_set_chip_select(struct mmc_host *host, int mode);  void mmc_set_clock(struct mmc_host *host, unsigned int hz); +void mmc_gate_clock(struct mmc_host *host); +void mmc_ungate_clock(struct mmc_host *host); +void mmc_set_ungated(struct mmc_host *host);  void mmc_set_bus_mode(struct mmc_host *host, unsigned int mode);  void mmc_set_bus_width(struct mmc_host *host, unsigned int width); -void mmc_set_bus_width_ddr(struct mmc_host *host, unsigned int width, -			   unsigned int ddr);  u32 mmc_select_voltage(struct mmc_host *host, u32 ocr); +int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage, u32 ocr); +int __mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage);  void mmc_set_timing(struct mmc_host *host, unsigned int timing); +void mmc_set_driver_type(struct mmc_host *host, unsigned int drv_type); +void mmc_power_up(struct mmc_host *host, u32 ocr); +void mmc_power_off(struct mmc_host *host); +void mmc_power_cycle(struct mmc_host *host, u32 ocr);  static inline void mmc_delay(unsigned int ms)  { @@ -54,12 +64,14 @@ void mmc_rescan(struct work_struct *work);  void mmc_start_host(struct mmc_host *host);  void mmc_stop_host(struct mmc_host *host); -int mmc_attach_mmc(struct mmc_host *host, u32 ocr); -int mmc_attach_sd(struct mmc_host *host, u32 ocr); -int mmc_attach_sdio(struct mmc_host *host, u32 ocr); +int _mmc_detect_card_removed(struct mmc_host *host); + +int mmc_attach_mmc(struct mmc_host *host); +int mmc_attach_sd(struct mmc_host *host); +int mmc_attach_sdio(struct mmc_host *host);  /* Module parameters */ -extern int use_spi_crc; +extern bool use_spi_crc;  /* Debugfs information for hosts and cards */  void mmc_add_host_debugfs(struct mmc_host *host); @@ -68,5 +80,6 @@ void mmc_remove_host_debugfs(struct mmc_host *host);  void mmc_add_card_debugfs(struct mmc_card *card);  void mmc_remove_card_debugfs(struct mmc_card *card); +void mmc_init_context_info(struct mmc_host *host);  #endif diff --git a/drivers/mmc/core/debugfs.c b/drivers/mmc/core/debugfs.c index eed1405fd74..91eb1622324 100644 --- a/drivers/mmc/core/debugfs.c +++ b/drivers/mmc/core/debugfs.c @@ -7,11 +7,14 @@   * it under the terms of the GNU General Public License version 2 as   * published by the Free Software Foundation.   */ +#include <linux/moduleparam.h> +#include <linux/export.h>  #include <linux/debugfs.h>  #include <linux/fs.h>  #include <linux/seq_file.h>  #include <linux/slab.h>  #include <linux/stat.h> +#include <linux/fault-inject.h>  #include <linux/mmc/card.h>  #include <linux/mmc/host.h> @@ -19,6 +22,14 @@  #include "core.h"  #include "mmc_ops.h" +#ifdef CONFIG_FAIL_MMC_REQUEST + +static DECLARE_FAULT_ATTR(fail_default_attr); +static char *fail_request; +module_param(fail_request, charp, 0); + +#endif /* CONFIG_FAIL_MMC_REQUEST */ +  /* The debugfs functions are optimized away when CONFIG_DEBUG_FS isn't set. */  static int mmc_ios_show(struct seq_file *s, void *data)  { @@ -46,6 +57,8 @@ static int mmc_ios_show(struct seq_file *s, void *data)  	const char *str;  	seq_printf(s, "clock:\t\t%u Hz\n", ios->clock); +	if (host->actual_clock) +		seq_printf(s, "actual clock:\t%u Hz\n", host->actual_clock);  	seq_printf(s, "vdd:\t\t%u ", ios->vdd);  	if ((1 << ios->vdd) & MMC_VDD_165_195)  		seq_printf(s, "(1.65 - 1.95 V)\n"); @@ -113,12 +126,46 @@ static int mmc_ios_show(struct seq_file *s, void *data)  	case MMC_TIMING_SD_HS:  		str = "sd high-speed";  		break; +	case MMC_TIMING_UHS_SDR50: +		str = "sd uhs SDR50"; +		break; +	case MMC_TIMING_UHS_SDR104: +		str = "sd uhs SDR104"; +		break; +	case MMC_TIMING_UHS_DDR50: +		str = "sd uhs DDR50"; +		break; +	case MMC_TIMING_MMC_DDR52: +		str = "mmc DDR52"; +		break; +	case MMC_TIMING_MMC_HS200: +		str = "mmc HS200"; +		break; +	case MMC_TIMING_MMC_HS400: +		str = "mmc HS400"; +		break;  	default:  		str = "invalid";  		break;  	}  	seq_printf(s, "timing spec:\t%u (%s)\n", ios->timing, str); +	switch (ios->signal_voltage) { +	case MMC_SIGNAL_VOLTAGE_330: +		str = "3.30 V"; +		break; +	case MMC_SIGNAL_VOLTAGE_180: +		str = "1.80 V"; +		break; +	case MMC_SIGNAL_VOLTAGE_120: +		str = "1.20 V"; +		break; +	default: +		str = "invalid"; +		break; +	} +	seq_printf(s, "signal voltage:\t%u (%s)\n", ios->chip_select, str); +  	return 0;  } @@ -183,6 +230,20 @@ void mmc_add_host_debugfs(struct mmc_host *host)  			&mmc_clock_fops))  		goto err_node; +#ifdef CONFIG_MMC_CLKGATE +	if (!debugfs_create_u32("clk_delay", (S_IRUSR | S_IWUSR), +				root, &host->clk_delay)) +		goto err_node; +#endif +#ifdef CONFIG_FAIL_MMC_REQUEST +	if (fail_request) +		setup_fault_attr(&fail_default_attr, fail_request); +	host->fail_mmc_request = fail_default_attr; +	if (IS_ERR(fault_create_debugfs_attr("fail_mmc_request", +					     root, +					     &host->fail_mmc_request))) +		goto err_node; +#endif  	return;  err_node: @@ -203,13 +264,13 @@ static int mmc_dbg_card_status_get(void *data, u64 *val)  	u32		status;  	int		ret; -	mmc_claim_host(card->host); +	mmc_get_card(card);  	ret = mmc_send_status(data, &status);  	if (!ret)  		*val = status; -	mmc_release_host(card->host); +	mmc_put_card(card);  	return ret;  } @@ -236,13 +297,13 @@ static int mmc_ext_csd_open(struct inode *inode, struct file *filp)  		goto out_free;  	} -	mmc_claim_host(card->host); +	mmc_get_card(card);  	err = mmc_send_ext_csd(card, ext_csd); -	mmc_release_host(card->host); +	mmc_put_card(card);  	if (err)  		goto out_free; -	for (i = 511; i >= 0; i--) +	for (i = 0; i < 512; i++)  		n += sprintf(buf + n, "%02x", ext_csd[i]);  	n += sprintf(buf + n, "\n");  	BUG_ON(n != EXT_CSD_STR_LEN); diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c index 10b8af27e03..95cceae9694 100644 --- a/drivers/mmc/core/host.c +++ b/drivers/mmc/core/host.c @@ -3,6 +3,7 @@   *   *  Copyright (C) 2003 Russell King, All Rights Reserved.   *  Copyright (C) 2007-2008 Pierre Ossman + *  Copyright (C) 2010 Linus Walleij   *   * This program is free software; you can redistribute it and/or modify   * it under the terms of the GNU General Public License version 2 as @@ -14,12 +15,17 @@  #include <linux/device.h>  #include <linux/err.h>  #include <linux/idr.h> +#include <linux/of.h> +#include <linux/of_gpio.h>  #include <linux/pagemap.h> +#include <linux/export.h>  #include <linux/leds.h>  #include <linux/slab.h>  #include <linux/suspend.h>  #include <linux/mmc/host.h> +#include <linux/mmc/card.h> +#include <linux/mmc/slot-gpio.h>  #include "core.h"  #include "host.h" @@ -29,6 +35,7 @@  static void mmc_host_classdev_release(struct device *dev)  {  	struct mmc_host *host = cls_dev_to_mmc_host(dev); +	mutex_destroy(&host->slot.lock);  	kfree(host);  } @@ -50,6 +57,410 @@ void mmc_unregister_host_class(void)  static DEFINE_IDR(mmc_host_idr);  static DEFINE_SPINLOCK(mmc_host_lock); +#ifdef CONFIG_MMC_CLKGATE +static ssize_t clkgate_delay_show(struct device *dev, +		struct device_attribute *attr, char *buf) +{ +	struct mmc_host *host = cls_dev_to_mmc_host(dev); +	return snprintf(buf, PAGE_SIZE, "%lu\n", host->clkgate_delay); +} + +static ssize_t clkgate_delay_store(struct device *dev, +		struct device_attribute *attr, const char *buf, size_t count) +{ +	struct mmc_host *host = cls_dev_to_mmc_host(dev); +	unsigned long flags, value; + +	if (kstrtoul(buf, 0, &value)) +		return -EINVAL; + +	spin_lock_irqsave(&host->clk_lock, flags); +	host->clkgate_delay = value; +	spin_unlock_irqrestore(&host->clk_lock, flags); +	return count; +} + +/* + * Enabling clock gating will make the core call out to the host + * once up and once down when it performs a request or card operation + * intermingled in any fashion. The driver will see this through + * set_ios() operations with ios.clock field set to 0 to gate (disable) + * the block clock, and to the old frequency to enable it again. + */ +static void mmc_host_clk_gate_delayed(struct mmc_host *host) +{ +	unsigned long tick_ns; +	unsigned long freq = host->ios.clock; +	unsigned long flags; + +	if (!freq) { +		pr_debug("%s: frequency set to 0 in disable function, " +			 "this means the clock is already disabled.\n", +			 mmc_hostname(host)); +		return; +	} +	/* +	 * New requests may have appeared while we were scheduling, +	 * then there is no reason to delay the check before +	 * clk_disable(). +	 */ +	spin_lock_irqsave(&host->clk_lock, flags); + +	/* +	 * Delay n bus cycles (at least 8 from MMC spec) before attempting +	 * to disable the MCI block clock. The reference count may have +	 * gone up again after this delay due to rescheduling! +	 */ +	if (!host->clk_requests) { +		spin_unlock_irqrestore(&host->clk_lock, flags); +		tick_ns = DIV_ROUND_UP(1000000000, freq); +		ndelay(host->clk_delay * tick_ns); +	} else { +		/* New users appeared while waiting for this work */ +		spin_unlock_irqrestore(&host->clk_lock, flags); +		return; +	} +	mutex_lock(&host->clk_gate_mutex); +	spin_lock_irqsave(&host->clk_lock, flags); +	if (!host->clk_requests) { +		spin_unlock_irqrestore(&host->clk_lock, flags); +		/* This will set host->ios.clock to 0 */ +		mmc_gate_clock(host); +		spin_lock_irqsave(&host->clk_lock, flags); +		pr_debug("%s: gated MCI clock\n", mmc_hostname(host)); +	} +	spin_unlock_irqrestore(&host->clk_lock, flags); +	mutex_unlock(&host->clk_gate_mutex); +} + +/* + * Internal work. Work to disable the clock at some later point. + */ +static void mmc_host_clk_gate_work(struct work_struct *work) +{ +	struct mmc_host *host = container_of(work, struct mmc_host, +					      clk_gate_work.work); + +	mmc_host_clk_gate_delayed(host); +} + +/** + *	mmc_host_clk_hold - ungate hardware MCI clocks + *	@host: host to ungate. + * + *	Makes sure the host ios.clock is restored to a non-zero value + *	past this call.	Increase clock reference count and ungate clock + *	if we're the first user. + */ +void mmc_host_clk_hold(struct mmc_host *host) +{ +	unsigned long flags; + +	/* cancel any clock gating work scheduled by mmc_host_clk_release() */ +	cancel_delayed_work_sync(&host->clk_gate_work); +	mutex_lock(&host->clk_gate_mutex); +	spin_lock_irqsave(&host->clk_lock, flags); +	if (host->clk_gated) { +		spin_unlock_irqrestore(&host->clk_lock, flags); +		mmc_ungate_clock(host); +		spin_lock_irqsave(&host->clk_lock, flags); +		pr_debug("%s: ungated MCI clock\n", mmc_hostname(host)); +	} +	host->clk_requests++; +	spin_unlock_irqrestore(&host->clk_lock, flags); +	mutex_unlock(&host->clk_gate_mutex); +} + +/** + *	mmc_host_may_gate_card - check if this card may be gated + *	@card: card to check. + */ +static bool mmc_host_may_gate_card(struct mmc_card *card) +{ +	/* If there is no card we may gate it */ +	if (!card) +		return true; +	/* +	 * Don't gate SDIO cards! These need to be clocked at all times +	 * since they may be independent systems generating interrupts +	 * and other events. The clock requests counter from the core will +	 * go down to zero since the core does not need it, but we will not +	 * gate the clock, because there is somebody out there that may still +	 * be using it. +	 */ +	return !(card->quirks & MMC_QUIRK_BROKEN_CLK_GATING); +} + +/** + *	mmc_host_clk_release - gate off hardware MCI clocks + *	@host: host to gate. + * + *	Calls the host driver with ios.clock set to zero as often as possible + *	in order to gate off hardware MCI clocks. Decrease clock reference + *	count and schedule disabling of clock. + */ +void mmc_host_clk_release(struct mmc_host *host) +{ +	unsigned long flags; + +	spin_lock_irqsave(&host->clk_lock, flags); +	host->clk_requests--; +	if (mmc_host_may_gate_card(host->card) && +	    !host->clk_requests) +		schedule_delayed_work(&host->clk_gate_work, +				      msecs_to_jiffies(host->clkgate_delay)); +	spin_unlock_irqrestore(&host->clk_lock, flags); +} + +/** + *	mmc_host_clk_rate - get current clock frequency setting + *	@host: host to get the clock frequency for. + * + *	Returns current clock frequency regardless of gating. + */ +unsigned int mmc_host_clk_rate(struct mmc_host *host) +{ +	unsigned long freq; +	unsigned long flags; + +	spin_lock_irqsave(&host->clk_lock, flags); +	if (host->clk_gated) +		freq = host->clk_old; +	else +		freq = host->ios.clock; +	spin_unlock_irqrestore(&host->clk_lock, flags); +	return freq; +} + +/** + *	mmc_host_clk_init - set up clock gating code + *	@host: host with potential clock to control + */ +static inline void mmc_host_clk_init(struct mmc_host *host) +{ +	host->clk_requests = 0; +	/* Hold MCI clock for 8 cycles by default */ +	host->clk_delay = 8; +	/* +	 * Default clock gating delay is 0ms to avoid wasting power. +	 * This value can be tuned by writing into sysfs entry. +	 */ +	host->clkgate_delay = 0; +	host->clk_gated = false; +	INIT_DELAYED_WORK(&host->clk_gate_work, mmc_host_clk_gate_work); +	spin_lock_init(&host->clk_lock); +	mutex_init(&host->clk_gate_mutex); +} + +/** + *	mmc_host_clk_exit - shut down clock gating code + *	@host: host with potential clock to control + */ +static inline void mmc_host_clk_exit(struct mmc_host *host) +{ +	/* +	 * Wait for any outstanding gate and then make sure we're +	 * ungated before exiting. +	 */ +	if (cancel_delayed_work_sync(&host->clk_gate_work)) +		mmc_host_clk_gate_delayed(host); +	if (host->clk_gated) +		mmc_host_clk_hold(host); +	/* There should be only one user now */ +	WARN_ON(host->clk_requests > 1); +} + +static inline void mmc_host_clk_sysfs_init(struct mmc_host *host) +{ +	host->clkgate_delay_attr.show = clkgate_delay_show; +	host->clkgate_delay_attr.store = clkgate_delay_store; +	sysfs_attr_init(&host->clkgate_delay_attr.attr); +	host->clkgate_delay_attr.attr.name = "clkgate_delay"; +	host->clkgate_delay_attr.attr.mode = S_IRUGO | S_IWUSR; +	if (device_create_file(&host->class_dev, &host->clkgate_delay_attr)) +		pr_err("%s: Failed to create clkgate_delay sysfs entry\n", +				mmc_hostname(host)); +} +#else + +static inline void mmc_host_clk_init(struct mmc_host *host) +{ +} + +static inline void mmc_host_clk_exit(struct mmc_host *host) +{ +} + +static inline void mmc_host_clk_sysfs_init(struct mmc_host *host) +{ +} + +#endif + +/** + *	mmc_of_parse() - parse host's device-tree node + *	@host: host whose node should be parsed. + * + * To keep the rest of the MMC subsystem unaware of whether DT has been + * used to to instantiate and configure this host instance or not, we + * parse the properties and set respective generic mmc-host flags and + * parameters. + */ +int mmc_of_parse(struct mmc_host *host) +{ +	struct device_node *np; +	u32 bus_width; +	bool explicit_inv_wp, gpio_inv_wp = false; +	enum of_gpio_flags flags; +	int len, ret, gpio; + +	if (!host->parent || !host->parent->of_node) +		return 0; + +	np = host->parent->of_node; + +	/* "bus-width" is translated to MMC_CAP_*_BIT_DATA flags */ +	if (of_property_read_u32(np, "bus-width", &bus_width) < 0) { +		dev_dbg(host->parent, +			"\"bus-width\" property is missing, assuming 1 bit.\n"); +		bus_width = 1; +	} + +	switch (bus_width) { +	case 8: +		host->caps |= MMC_CAP_8_BIT_DATA; +		/* Hosts capable of 8-bit transfers can also do 4 bits */ +	case 4: +		host->caps |= MMC_CAP_4_BIT_DATA; +		break; +	case 1: +		break; +	default: +		dev_err(host->parent, +			"Invalid \"bus-width\" value %u!\n", bus_width); +		return -EINVAL; +	} + +	/* f_max is obtained from the optional "max-frequency" property */ +	of_property_read_u32(np, "max-frequency", &host->f_max); + +	/* +	 * Configure CD and WP pins. They are both by default active low to +	 * match the SDHCI spec. If GPIOs are provided for CD and / or WP, the +	 * mmc-gpio helpers are used to attach, configure and use them. If +	 * polarity inversion is specified in DT, one of MMC_CAP2_CD_ACTIVE_HIGH +	 * and MMC_CAP2_RO_ACTIVE_HIGH capability-2 flags is set. If the +	 * "broken-cd" property is provided, the MMC_CAP_NEEDS_POLL capability +	 * is set. If the "non-removable" property is found, the +	 * MMC_CAP_NONREMOVABLE capability is set and no card-detection +	 * configuration is performed. +	 */ + +	/* Parse Card Detection */ +	if (of_find_property(np, "non-removable", &len)) { +		host->caps |= MMC_CAP_NONREMOVABLE; +	} else { +		bool explicit_inv_cd, gpio_inv_cd = false; + +		explicit_inv_cd = of_property_read_bool(np, "cd-inverted"); + +		if (of_find_property(np, "broken-cd", &len)) +			host->caps |= MMC_CAP_NEEDS_POLL; + +		gpio = of_get_named_gpio_flags(np, "cd-gpios", 0, &flags); +		if (gpio == -EPROBE_DEFER) +			return gpio; +		if (gpio_is_valid(gpio)) { +			if (!(flags & OF_GPIO_ACTIVE_LOW)) +				gpio_inv_cd = true; + +			ret = mmc_gpio_request_cd(host, gpio, 0); +			if (ret < 0) { +				dev_err(host->parent, +					"Failed to request CD GPIO #%d: %d!\n", +					gpio, ret); +				return ret; +			} else { +				dev_info(host->parent, "Got CD GPIO #%d.\n", +					 gpio); +			} +		} + +		if (explicit_inv_cd ^ gpio_inv_cd) +			host->caps2 |= MMC_CAP2_CD_ACTIVE_HIGH; +	} + +	/* Parse Write Protection */ +	explicit_inv_wp = of_property_read_bool(np, "wp-inverted"); + +	gpio = of_get_named_gpio_flags(np, "wp-gpios", 0, &flags); +	if (gpio == -EPROBE_DEFER) { +		ret = -EPROBE_DEFER; +		goto out; +	} +	if (gpio_is_valid(gpio)) { +		if (!(flags & OF_GPIO_ACTIVE_LOW)) +			gpio_inv_wp = true; + +		ret = mmc_gpio_request_ro(host, gpio); +		if (ret < 0) { +			dev_err(host->parent, +				"Failed to request WP GPIO: %d!\n", ret); +			goto out; +		} else { +				dev_info(host->parent, "Got WP GPIO #%d.\n", +					 gpio); +		} +	} +	if (explicit_inv_wp ^ gpio_inv_wp) +		host->caps2 |= MMC_CAP2_RO_ACTIVE_HIGH; + +	if (of_find_property(np, "cap-sd-highspeed", &len)) +		host->caps |= MMC_CAP_SD_HIGHSPEED; +	if (of_find_property(np, "cap-mmc-highspeed", &len)) +		host->caps |= MMC_CAP_MMC_HIGHSPEED; +	if (of_find_property(np, "sd-uhs-sdr12", &len)) +		host->caps |= MMC_CAP_UHS_SDR12; +	if (of_find_property(np, "sd-uhs-sdr25", &len)) +		host->caps |= MMC_CAP_UHS_SDR25; +	if (of_find_property(np, "sd-uhs-sdr50", &len)) +		host->caps |= MMC_CAP_UHS_SDR50; +	if (of_find_property(np, "sd-uhs-sdr104", &len)) +		host->caps |= MMC_CAP_UHS_SDR104; +	if (of_find_property(np, "sd-uhs-ddr50", &len)) +		host->caps |= MMC_CAP_UHS_DDR50; +	if (of_find_property(np, "cap-power-off-card", &len)) +		host->caps |= MMC_CAP_POWER_OFF_CARD; +	if (of_find_property(np, "cap-sdio-irq", &len)) +		host->caps |= MMC_CAP_SDIO_IRQ; +	if (of_find_property(np, "full-pwr-cycle", &len)) +		host->caps2 |= MMC_CAP2_FULL_PWR_CYCLE; +	if (of_find_property(np, "keep-power-in-suspend", &len)) +		host->pm_caps |= MMC_PM_KEEP_POWER; +	if (of_find_property(np, "enable-sdio-wakeup", &len)) +		host->pm_caps |= MMC_PM_WAKE_SDIO_IRQ; +	if (of_find_property(np, "mmc-ddr-1_8v", &len)) +		host->caps |= MMC_CAP_1_8V_DDR; +	if (of_find_property(np, "mmc-ddr-1_2v", &len)) +		host->caps |= MMC_CAP_1_2V_DDR; +	if (of_find_property(np, "mmc-hs200-1_8v", &len)) +		host->caps2 |= MMC_CAP2_HS200_1_8V_SDR; +	if (of_find_property(np, "mmc-hs200-1_2v", &len)) +		host->caps2 |= MMC_CAP2_HS200_1_2V_SDR; +	if (of_find_property(np, "mmc-hs400-1_8v", &len)) +		host->caps2 |= MMC_CAP2_HS400_1_8V | MMC_CAP2_HS200_1_8V_SDR; +	if (of_find_property(np, "mmc-hs400-1_2v", &len)) +		host->caps2 |= MMC_CAP2_HS400_1_2V | MMC_CAP2_HS200_1_2V_SDR; + +	return 0; + +out: +	mmc_gpio_free_cd(host); +	return ret; +} + +EXPORT_SYMBOL(mmc_of_parse); +  /**   *	mmc_alloc_host - initialise the per-host structure.   *	@extra: sizeof private data structure @@ -62,17 +473,20 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev)  	int err;  	struct mmc_host *host; -	if (!idr_pre_get(&mmc_host_idr, GFP_KERNEL)) -		return NULL; -  	host = kzalloc(sizeof(struct mmc_host) + extra, GFP_KERNEL);  	if (!host)  		return NULL; +	/* scanning will be enabled when we're ready */ +	host->rescan_disable = 1; +	idr_preload(GFP_KERNEL);  	spin_lock(&mmc_host_lock); -	err = idr_get_new(&mmc_host_idr, host, &host->index); +	err = idr_alloc(&mmc_host_idr, host, 0, 0, GFP_NOWAIT); +	if (err >= 0) +		host->index = err;  	spin_unlock(&mmc_host_lock); -	if (err) +	idr_preload_end(); +	if (err < 0)  		goto free;  	dev_set_name(&host->class_dev, "mmc%d", host->index); @@ -82,10 +496,14 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev)  	host->class_dev.class = &mmc_host_class;  	device_initialize(&host->class_dev); +	mmc_host_clk_init(host); + +	mutex_init(&host->slot.lock); +	host->slot.cd_irq = -EINVAL; +  	spin_lock_init(&host->lock);  	init_waitqueue_head(&host->wq);  	INIT_DELAYED_WORK(&host->detect, mmc_rescan); -	INIT_DELAYED_WORK_DEFERRABLE(&host->disable, mmc_host_deeper_disable);  #ifdef CONFIG_PM  	host->pm_notify.notifier_call = mmc_pm_notify;  #endif @@ -125,15 +543,16 @@ int mmc_add_host(struct mmc_host *host)  	WARN_ON((host->caps & MMC_CAP_SDIO_IRQ) &&  		!host->ops->enable_sdio_irq); -	led_trigger_register_simple(dev_name(&host->class_dev), &host->led); -  	err = device_add(&host->class_dev);  	if (err)  		return err; +	led_trigger_register_simple(dev_name(&host->class_dev), &host->led); +  #ifdef CONFIG_DEBUG_FS  	mmc_add_host_debugfs(host);  #endif +	mmc_host_clk_sysfs_init(host);  	mmc_start_host(host);  	register_pm_notifier(&host->pm_notify); @@ -163,6 +582,8 @@ void mmc_remove_host(struct mmc_host *host)  	device_del(&host->class_dev);  	led_trigger_unregister_simple(host->led); + +	mmc_host_clk_exit(host);  }  EXPORT_SYMBOL(mmc_remove_host); @@ -183,4 +604,3 @@ void mmc_free_host(struct mmc_host *host)  }  EXPORT_SYMBOL(mmc_free_host); - diff --git a/drivers/mmc/core/host.h b/drivers/mmc/core/host.h index 8c87e1109a3..f2ab9e57812 100644 --- a/drivers/mmc/core/host.h +++ b/drivers/mmc/core/host.h @@ -10,11 +10,10 @@   */  #ifndef _MMC_CORE_HOST_H  #define _MMC_CORE_HOST_H +#include <linux/mmc/host.h>  int mmc_register_host_class(void);  void mmc_unregister_host_class(void); -void mmc_host_deeper_disable(struct work_struct *work); -  #endif diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 995261f7fd7..793c6f7ddb0 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -12,6 +12,8 @@  #include <linux/err.h>  #include <linux/slab.h> +#include <linux/stat.h> +#include <linux/pm_runtime.h>  #include <linux/mmc/host.h>  #include <linux/mmc/card.h> @@ -20,6 +22,7 @@  #include "core.h"  #include "bus.h"  #include "mmc_ops.h" +#include "sd_ops.h"  static const unsigned int tran_exp[] = {  	10000,		100000,		1000000,	10000000, @@ -94,13 +97,14 @@ static int mmc_decode_cid(struct mmc_card *card)  		card->cid.prod_name[3]	= UNSTUFF_BITS(resp, 72, 8);  		card->cid.prod_name[4]	= UNSTUFF_BITS(resp, 64, 8);  		card->cid.prod_name[5]	= UNSTUFF_BITS(resp, 56, 8); +		card->cid.prv		= UNSTUFF_BITS(resp, 48, 8);  		card->cid.serial	= UNSTUFF_BITS(resp, 16, 32);  		card->cid.month		= UNSTUFF_BITS(resp, 12, 4);  		card->cid.year		= UNSTUFF_BITS(resp, 8, 4) + 1997;  		break;  	default: -		printk(KERN_ERR "%s: card has unknown MMCA version %d\n", +		pr_err("%s: card has unknown MMCA version %d\n",  			mmc_hostname(card->host), card->csd.mmca_vsn);  		return -EINVAL;  	} @@ -134,7 +138,7 @@ static int mmc_decode_csd(struct mmc_card *card)  	 */  	csd->structure = UNSTUFF_BITS(resp, 126, 2);  	if (csd->structure == 0) { -		printk(KERN_ERR "%s: unrecognised CSD structure version %d\n", +		pr_err("%s: unrecognised CSD structure version %d\n",  			mmc_hostname(card->host), csd->structure);  		return -EINVAL;  	} @@ -173,14 +177,17 @@ static int mmc_decode_csd(struct mmc_card *card)  }  /* - * Read and decode extended CSD. + * Read extended CSD.   */ -static int mmc_read_ext_csd(struct mmc_card *card) +static int mmc_get_ext_csd(struct mmc_card *card, u8 **new_ext_csd)  {  	int err;  	u8 *ext_csd;  	BUG_ON(!card); +	BUG_ON(!new_ext_csd); + +	*new_ext_csd = NULL;  	if (card->csd.mmca_vsn < CSD_SPEC_VER_4)  		return 0; @@ -191,60 +198,144 @@ static int mmc_read_ext_csd(struct mmc_card *card)  	 */  	ext_csd = kmalloc(512, GFP_KERNEL);  	if (!ext_csd) { -		printk(KERN_ERR "%s: could not allocate a buffer to " +		pr_err("%s: could not allocate a buffer to "  			"receive the ext_csd.\n", mmc_hostname(card->host));  		return -ENOMEM;  	}  	err = mmc_send_ext_csd(card, ext_csd);  	if (err) { +		kfree(ext_csd); +		*new_ext_csd = NULL; +  		/* If the host or the card can't do the switch,  		 * fail more gracefully. */  		if ((err != -EINVAL)  		 && (err != -ENOSYS)  		 && (err != -EFAULT)) -			goto out; +			return err;  		/*  		 * High capacity cards should have this "magic" size  		 * stored in their CSD.  		 */  		if (card->csd.capacity == (4096 * 512)) { -			printk(KERN_ERR "%s: unable to read EXT_CSD " +			pr_err("%s: unable to read EXT_CSD "  				"on a possible high capacity card. "  				"Card will be ignored.\n",  				mmc_hostname(card->host));  		} else { -			printk(KERN_WARNING "%s: unable to read " +			pr_warning("%s: unable to read "  				"EXT_CSD, performance might "  				"suffer.\n",  				mmc_hostname(card->host));  			err = 0;  		} +	} else +		*new_ext_csd = ext_csd; -		goto out; +	return err; +} + +static void mmc_select_card_type(struct mmc_card *card) +{ +	struct mmc_host *host = card->host; +	u8 card_type = card->ext_csd.raw_card_type; +	u32 caps = host->caps, caps2 = host->caps2; +	unsigned int hs_max_dtr = 0, hs200_max_dtr = 0; +	unsigned int avail_type = 0; + +	if (caps & MMC_CAP_MMC_HIGHSPEED && +	    card_type & EXT_CSD_CARD_TYPE_HS_26) { +		hs_max_dtr = MMC_HIGH_26_MAX_DTR; +		avail_type |= EXT_CSD_CARD_TYPE_HS_26; +	} + +	if (caps & MMC_CAP_MMC_HIGHSPEED && +	    card_type & EXT_CSD_CARD_TYPE_HS_52) { +		hs_max_dtr = MMC_HIGH_52_MAX_DTR; +		avail_type |= EXT_CSD_CARD_TYPE_HS_52; +	} + +	if (caps & MMC_CAP_1_8V_DDR && +	    card_type & EXT_CSD_CARD_TYPE_DDR_1_8V) { +		hs_max_dtr = MMC_HIGH_DDR_MAX_DTR; +		avail_type |= EXT_CSD_CARD_TYPE_DDR_1_8V; +	} + +	if (caps & MMC_CAP_1_2V_DDR && +	    card_type & EXT_CSD_CARD_TYPE_DDR_1_2V) { +		hs_max_dtr = MMC_HIGH_DDR_MAX_DTR; +		avail_type |= EXT_CSD_CARD_TYPE_DDR_1_2V; +	} + +	if (caps2 & MMC_CAP2_HS200_1_8V_SDR && +	    card_type & EXT_CSD_CARD_TYPE_HS200_1_8V) { +		hs200_max_dtr = MMC_HS200_MAX_DTR; +		avail_type |= EXT_CSD_CARD_TYPE_HS200_1_8V; +	} + +	if (caps2 & MMC_CAP2_HS200_1_2V_SDR && +	    card_type & EXT_CSD_CARD_TYPE_HS200_1_2V) { +		hs200_max_dtr = MMC_HS200_MAX_DTR; +		avail_type |= EXT_CSD_CARD_TYPE_HS200_1_2V; +	} + +	if (caps2 & MMC_CAP2_HS400_1_8V && +	    card_type & EXT_CSD_CARD_TYPE_HS400_1_8V) { +		hs200_max_dtr = MMC_HS200_MAX_DTR; +		avail_type |= EXT_CSD_CARD_TYPE_HS400_1_8V; +	} + +	if (caps2 & MMC_CAP2_HS400_1_2V && +	    card_type & EXT_CSD_CARD_TYPE_HS400_1_2V) { +		hs200_max_dtr = MMC_HS200_MAX_DTR; +		avail_type |= EXT_CSD_CARD_TYPE_HS400_1_2V;  	} +	card->ext_csd.hs_max_dtr = hs_max_dtr; +	card->ext_csd.hs200_max_dtr = hs200_max_dtr; +	card->mmc_avail_type = avail_type; +} + +/* + * Decode extended CSD. + */ +static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) +{ +	int err = 0, idx; +	unsigned int part_size; +	u8 hc_erase_grp_sz = 0, hc_wp_grp_sz = 0; + +	BUG_ON(!card); + +	if (!ext_csd) +		return 0; +  	/* Version is coded in the CSD_STRUCTURE byte in the EXT_CSD register */ +	card->ext_csd.raw_ext_csd_structure = ext_csd[EXT_CSD_STRUCTURE];  	if (card->csd.structure == 3) { -		int ext_csd_struct = ext_csd[EXT_CSD_STRUCTURE]; -		if (ext_csd_struct > 2) { -			printk(KERN_ERR "%s: unrecognised EXT_CSD structure " +		if (card->ext_csd.raw_ext_csd_structure > 2) { +			pr_err("%s: unrecognised EXT_CSD structure "  				"version %d\n", mmc_hostname(card->host), -					ext_csd_struct); +					card->ext_csd.raw_ext_csd_structure);  			err = -EINVAL;  			goto out;  		}  	}  	card->ext_csd.rev = ext_csd[EXT_CSD_REV]; -	if (card->ext_csd.rev > 5) { -		printk(KERN_ERR "%s: unrecognised EXT_CSD revision %d\n", +	if (card->ext_csd.rev > 7) { +		pr_err("%s: unrecognised EXT_CSD revision %d\n",  			mmc_hostname(card->host), card->ext_csd.rev);  		err = -EINVAL;  		goto out;  	} +	card->ext_csd.raw_sectors[0] = ext_csd[EXT_CSD_SEC_CNT + 0]; +	card->ext_csd.raw_sectors[1] = ext_csd[EXT_CSD_SEC_CNT + 1]; +	card->ext_csd.raw_sectors[2] = ext_csd[EXT_CSD_SEC_CNT + 2]; +	card->ext_csd.raw_sectors[3] = ext_csd[EXT_CSD_SEC_CNT + 3];  	if (card->ext_csd.rev >= 2) {  		card->ext_csd.sectors =  			ext_csd[EXT_CSD_SEC_CNT + 0] << 0 | @@ -257,37 +348,20 @@ static int mmc_read_ext_csd(struct mmc_card *card)  			mmc_card_set_blockaddr(card);  	} -	switch (ext_csd[EXT_CSD_CARD_TYPE] & EXT_CSD_CARD_TYPE_MASK) { -	case EXT_CSD_CARD_TYPE_DDR_52 | EXT_CSD_CARD_TYPE_52 | -	     EXT_CSD_CARD_TYPE_26: -		card->ext_csd.hs_max_dtr = 52000000; -		card->ext_csd.card_type = EXT_CSD_CARD_TYPE_DDR_52; -		break; -	case EXT_CSD_CARD_TYPE_DDR_1_2V | EXT_CSD_CARD_TYPE_52 | -	     EXT_CSD_CARD_TYPE_26: -		card->ext_csd.hs_max_dtr = 52000000; -		card->ext_csd.card_type = EXT_CSD_CARD_TYPE_DDR_1_2V; -		break; -	case EXT_CSD_CARD_TYPE_DDR_1_8V | EXT_CSD_CARD_TYPE_52 | -	     EXT_CSD_CARD_TYPE_26: -		card->ext_csd.hs_max_dtr = 52000000; -		card->ext_csd.card_type = EXT_CSD_CARD_TYPE_DDR_1_8V; -		break; -	case EXT_CSD_CARD_TYPE_52 | EXT_CSD_CARD_TYPE_26: -		card->ext_csd.hs_max_dtr = 52000000; -		break; -	case EXT_CSD_CARD_TYPE_26: -		card->ext_csd.hs_max_dtr = 26000000; -		break; -	default: -		/* MMC v4 spec says this cannot happen */ -		printk(KERN_WARNING "%s: card is mmc v4 but doesn't " -			"support any high-speed modes.\n", -			mmc_hostname(card->host)); -	} +	card->ext_csd.raw_card_type = ext_csd[EXT_CSD_CARD_TYPE]; +	mmc_select_card_type(card); +	card->ext_csd.raw_s_a_timeout = ext_csd[EXT_CSD_S_A_TIMEOUT]; +	card->ext_csd.raw_erase_timeout_mult = +		ext_csd[EXT_CSD_ERASE_TIMEOUT_MULT]; +	card->ext_csd.raw_hc_erase_grp_size = +		ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];  	if (card->ext_csd.rev >= 3) {  		u8 sa_shift = ext_csd[EXT_CSD_S_A_TIMEOUT]; +		card->ext_csd.part_config = ext_csd[EXT_CSD_PART_CONFIG]; + +		/* EXT_CSD value is in units of 10ms, but we store in ms */ +		card->ext_csd.part_time = 10 * ext_csd[EXT_CSD_PART_SWITCH_TIME];  		/* Sleep / awake timeout in 100ns units */  		if (sa_shift > 0 && sa_shift <= 0x17) @@ -299,9 +373,110 @@ static int mmc_read_ext_csd(struct mmc_card *card)  			ext_csd[EXT_CSD_ERASE_TIMEOUT_MULT];  		card->ext_csd.hc_erase_size =  			ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] << 10; + +		card->ext_csd.rel_sectors = ext_csd[EXT_CSD_REL_WR_SEC_C]; + +		/* +		 * There are two boot regions of equal size, defined in +		 * multiples of 128K. +		 */ +		if (ext_csd[EXT_CSD_BOOT_MULT] && mmc_boot_partition_access(card->host)) { +			for (idx = 0; idx < MMC_NUM_BOOT_PARTITION; idx++) { +				part_size = ext_csd[EXT_CSD_BOOT_MULT] << 17; +				mmc_part_add(card, part_size, +					EXT_CSD_PART_CONFIG_ACC_BOOT0 + idx, +					"boot%d", idx, true, +					MMC_BLK_DATA_AREA_BOOT); +			} +		}  	} +	card->ext_csd.raw_hc_erase_gap_size = +		ext_csd[EXT_CSD_HC_WP_GRP_SIZE]; +	card->ext_csd.raw_sec_trim_mult = +		ext_csd[EXT_CSD_SEC_TRIM_MULT]; +	card->ext_csd.raw_sec_erase_mult = +		ext_csd[EXT_CSD_SEC_ERASE_MULT]; +	card->ext_csd.raw_sec_feature_support = +		ext_csd[EXT_CSD_SEC_FEATURE_SUPPORT]; +	card->ext_csd.raw_trim_mult = +		ext_csd[EXT_CSD_TRIM_MULT]; +	card->ext_csd.raw_partition_support = ext_csd[EXT_CSD_PARTITION_SUPPORT];  	if (card->ext_csd.rev >= 4) { +		/* +		 * Enhanced area feature support -- check whether the eMMC +		 * card has the Enhanced area enabled.  If so, export enhanced +		 * area offset and size to user by adding sysfs interface. +		 */ +		if ((ext_csd[EXT_CSD_PARTITION_SUPPORT] & 0x2) && +		    (ext_csd[EXT_CSD_PARTITION_ATTRIBUTE] & 0x1)) { +			hc_erase_grp_sz = +				ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]; +			hc_wp_grp_sz = +				ext_csd[EXT_CSD_HC_WP_GRP_SIZE]; + +			card->ext_csd.enhanced_area_en = 1; +			/* +			 * calculate the enhanced data area offset, in bytes +			 */ +			card->ext_csd.enhanced_area_offset = +				(ext_csd[139] << 24) + (ext_csd[138] << 16) + +				(ext_csd[137] << 8) + ext_csd[136]; +			if (mmc_card_blockaddr(card)) +				card->ext_csd.enhanced_area_offset <<= 9; +			/* +			 * calculate the enhanced data area size, in kilobytes +			 */ +			card->ext_csd.enhanced_area_size = +				(ext_csd[142] << 16) + (ext_csd[141] << 8) + +				ext_csd[140]; +			card->ext_csd.enhanced_area_size *= +				(size_t)(hc_erase_grp_sz * hc_wp_grp_sz); +			card->ext_csd.enhanced_area_size <<= 9; +		} else { +			/* +			 * If the enhanced area is not enabled, disable these +			 * device attributes. +			 */ +			card->ext_csd.enhanced_area_offset = -EINVAL; +			card->ext_csd.enhanced_area_size = -EINVAL; +		} + +		/* +		 * General purpose partition feature support -- +		 * If ext_csd has the size of general purpose partitions, +		 * set size, part_cfg, partition name in mmc_part. +		 */ +		if (ext_csd[EXT_CSD_PARTITION_SUPPORT] & +			EXT_CSD_PART_SUPPORT_PART_EN) { +			if (card->ext_csd.enhanced_area_en != 1) { +				hc_erase_grp_sz = +					ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]; +				hc_wp_grp_sz = +					ext_csd[EXT_CSD_HC_WP_GRP_SIZE]; + +				card->ext_csd.enhanced_area_en = 1; +			} + +			for (idx = 0; idx < MMC_NUM_GP_PARTITION; idx++) { +				if (!ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3] && +				!ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3 + 1] && +				!ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3 + 2]) +					continue; +				part_size = +				(ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3 + 2] +					<< 16) + +				(ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3 + 1] +					<< 8) + +				ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3]; +				part_size *= (size_t)(hc_erase_grp_sz * +					hc_wp_grp_sz); +				mmc_part_add(card, part_size << 19, +					EXT_CSD_PART_CONFIG_ACC_GP0 + idx, +					"gp%d", idx, false, +					MMC_BLK_DATA_AREA_GP); +			} +		}  		card->ext_csd.sec_trim_mult =  			ext_csd[EXT_CSD_SEC_TRIM_MULT];  		card->ext_csd.sec_erase_mult = @@ -310,16 +485,209 @@ static int mmc_read_ext_csd(struct mmc_card *card)  			ext_csd[EXT_CSD_SEC_FEATURE_SUPPORT];  		card->ext_csd.trim_timeout = 300 *  			ext_csd[EXT_CSD_TRIM_MULT]; + +		/* +		 * Note that the call to mmc_part_add above defaults to read +		 * only. If this default assumption is changed, the call must +		 * take into account the value of boot_locked below. +		 */ +		card->ext_csd.boot_ro_lock = ext_csd[EXT_CSD_BOOT_WP]; +		card->ext_csd.boot_ro_lockable = true; + +		/* Save power class values */ +		card->ext_csd.raw_pwr_cl_52_195 = +			ext_csd[EXT_CSD_PWR_CL_52_195]; +		card->ext_csd.raw_pwr_cl_26_195 = +			ext_csd[EXT_CSD_PWR_CL_26_195]; +		card->ext_csd.raw_pwr_cl_52_360 = +			ext_csd[EXT_CSD_PWR_CL_52_360]; +		card->ext_csd.raw_pwr_cl_26_360 = +			ext_csd[EXT_CSD_PWR_CL_26_360]; +		card->ext_csd.raw_pwr_cl_200_195 = +			ext_csd[EXT_CSD_PWR_CL_200_195]; +		card->ext_csd.raw_pwr_cl_200_360 = +			ext_csd[EXT_CSD_PWR_CL_200_360]; +		card->ext_csd.raw_pwr_cl_ddr_52_195 = +			ext_csd[EXT_CSD_PWR_CL_DDR_52_195]; +		card->ext_csd.raw_pwr_cl_ddr_52_360 = +			ext_csd[EXT_CSD_PWR_CL_DDR_52_360]; +		card->ext_csd.raw_pwr_cl_ddr_200_360 = +			ext_csd[EXT_CSD_PWR_CL_DDR_200_360]; +	} + +	if (card->ext_csd.rev >= 5) { +		/* Adjust production date as per JEDEC JESD84-B451 */ +		if (card->cid.year < 2010) +			card->cid.year += 16; + +		/* check whether the eMMC card supports BKOPS */ +		if (ext_csd[EXT_CSD_BKOPS_SUPPORT] & 0x1) { +			card->ext_csd.bkops = 1; +			card->ext_csd.bkops_en = ext_csd[EXT_CSD_BKOPS_EN]; +			card->ext_csd.raw_bkops_status = +				ext_csd[EXT_CSD_BKOPS_STATUS]; +			if (!card->ext_csd.bkops_en) +				pr_info("%s: BKOPS_EN bit is not set\n", +					mmc_hostname(card->host)); +		} + +		/* check whether the eMMC card supports HPI */ +		if (ext_csd[EXT_CSD_HPI_FEATURES] & 0x1) { +			card->ext_csd.hpi = 1; +			if (ext_csd[EXT_CSD_HPI_FEATURES] & 0x2) +				card->ext_csd.hpi_cmd =	MMC_STOP_TRANSMISSION; +			else +				card->ext_csd.hpi_cmd = MMC_SEND_STATUS; +			/* +			 * Indicate the maximum timeout to close +			 * a command interrupted by HPI +			 */ +			card->ext_csd.out_of_int_time = +				ext_csd[EXT_CSD_OUT_OF_INTERRUPT_TIME] * 10; +		} + +		card->ext_csd.rel_param = ext_csd[EXT_CSD_WR_REL_PARAM]; +		card->ext_csd.rst_n_function = ext_csd[EXT_CSD_RST_N_FUNCTION]; + +		/* +		 * RPMB regions are defined in multiples of 128K. +		 */ +		card->ext_csd.raw_rpmb_size_mult = ext_csd[EXT_CSD_RPMB_MULT]; +		if (ext_csd[EXT_CSD_RPMB_MULT] && mmc_host_cmd23(card->host)) { +			mmc_part_add(card, ext_csd[EXT_CSD_RPMB_MULT] << 17, +				EXT_CSD_PART_CONFIG_ACC_RPMB, +				"rpmb", 0, false, +				MMC_BLK_DATA_AREA_RPMB); +		}  	} +	card->ext_csd.raw_erased_mem_count = ext_csd[EXT_CSD_ERASED_MEM_CONT];  	if (ext_csd[EXT_CSD_ERASED_MEM_CONT])  		card->erased_byte = 0xFF;  	else  		card->erased_byte = 0x0; +	/* eMMC v4.5 or later */ +	if (card->ext_csd.rev >= 6) { +		card->ext_csd.feature_support |= MMC_DISCARD_FEATURE; + +		card->ext_csd.generic_cmd6_time = 10 * +			ext_csd[EXT_CSD_GENERIC_CMD6_TIME]; +		card->ext_csd.power_off_longtime = 10 * +			ext_csd[EXT_CSD_POWER_OFF_LONG_TIME]; + +		card->ext_csd.cache_size = +			ext_csd[EXT_CSD_CACHE_SIZE + 0] << 0 | +			ext_csd[EXT_CSD_CACHE_SIZE + 1] << 8 | +			ext_csd[EXT_CSD_CACHE_SIZE + 2] << 16 | +			ext_csd[EXT_CSD_CACHE_SIZE + 3] << 24; + +		if (ext_csd[EXT_CSD_DATA_SECTOR_SIZE] == 1) +			card->ext_csd.data_sector_size = 4096; +		else +			card->ext_csd.data_sector_size = 512; + +		if ((ext_csd[EXT_CSD_DATA_TAG_SUPPORT] & 1) && +		    (ext_csd[EXT_CSD_TAG_UNIT_SIZE] <= 8)) { +			card->ext_csd.data_tag_unit_size = +			((unsigned int) 1 << ext_csd[EXT_CSD_TAG_UNIT_SIZE]) * +			(card->ext_csd.data_sector_size); +		} else { +			card->ext_csd.data_tag_unit_size = 0; +		} + +		card->ext_csd.max_packed_writes = +			ext_csd[EXT_CSD_MAX_PACKED_WRITES]; +		card->ext_csd.max_packed_reads = +			ext_csd[EXT_CSD_MAX_PACKED_READS]; +	} else { +		card->ext_csd.data_sector_size = 512; +	} +  out: +	return err; +} + +static inline void mmc_free_ext_csd(u8 *ext_csd) +{  	kfree(ext_csd); +} + +static int mmc_compare_ext_csds(struct mmc_card *card, unsigned bus_width) +{ +	u8 *bw_ext_csd; +	int err; + +	if (bus_width == MMC_BUS_WIDTH_1) +		return 0; + +	err = mmc_get_ext_csd(card, &bw_ext_csd); + +	if (err || bw_ext_csd == NULL) { +		err = -EINVAL; +		goto out; +	} + +	/* only compare read only fields */ +	err = !((card->ext_csd.raw_partition_support == +			bw_ext_csd[EXT_CSD_PARTITION_SUPPORT]) && +		(card->ext_csd.raw_erased_mem_count == +			bw_ext_csd[EXT_CSD_ERASED_MEM_CONT]) && +		(card->ext_csd.rev == +			bw_ext_csd[EXT_CSD_REV]) && +		(card->ext_csd.raw_ext_csd_structure == +			bw_ext_csd[EXT_CSD_STRUCTURE]) && +		(card->ext_csd.raw_card_type == +			bw_ext_csd[EXT_CSD_CARD_TYPE]) && +		(card->ext_csd.raw_s_a_timeout == +			bw_ext_csd[EXT_CSD_S_A_TIMEOUT]) && +		(card->ext_csd.raw_hc_erase_gap_size == +			bw_ext_csd[EXT_CSD_HC_WP_GRP_SIZE]) && +		(card->ext_csd.raw_erase_timeout_mult == +			bw_ext_csd[EXT_CSD_ERASE_TIMEOUT_MULT]) && +		(card->ext_csd.raw_hc_erase_grp_size == +			bw_ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]) && +		(card->ext_csd.raw_sec_trim_mult == +			bw_ext_csd[EXT_CSD_SEC_TRIM_MULT]) && +		(card->ext_csd.raw_sec_erase_mult == +			bw_ext_csd[EXT_CSD_SEC_ERASE_MULT]) && +		(card->ext_csd.raw_sec_feature_support == +			bw_ext_csd[EXT_CSD_SEC_FEATURE_SUPPORT]) && +		(card->ext_csd.raw_trim_mult == +			bw_ext_csd[EXT_CSD_TRIM_MULT]) && +		(card->ext_csd.raw_sectors[0] == +			bw_ext_csd[EXT_CSD_SEC_CNT + 0]) && +		(card->ext_csd.raw_sectors[1] == +			bw_ext_csd[EXT_CSD_SEC_CNT + 1]) && +		(card->ext_csd.raw_sectors[2] == +			bw_ext_csd[EXT_CSD_SEC_CNT + 2]) && +		(card->ext_csd.raw_sectors[3] == +			bw_ext_csd[EXT_CSD_SEC_CNT + 3]) && +		(card->ext_csd.raw_pwr_cl_52_195 == +			bw_ext_csd[EXT_CSD_PWR_CL_52_195]) && +		(card->ext_csd.raw_pwr_cl_26_195 == +			bw_ext_csd[EXT_CSD_PWR_CL_26_195]) && +		(card->ext_csd.raw_pwr_cl_52_360 == +			bw_ext_csd[EXT_CSD_PWR_CL_52_360]) && +		(card->ext_csd.raw_pwr_cl_26_360 == +			bw_ext_csd[EXT_CSD_PWR_CL_26_360]) && +		(card->ext_csd.raw_pwr_cl_200_195 == +			bw_ext_csd[EXT_CSD_PWR_CL_200_195]) && +		(card->ext_csd.raw_pwr_cl_200_360 == +			bw_ext_csd[EXT_CSD_PWR_CL_200_360]) && +		(card->ext_csd.raw_pwr_cl_ddr_52_195 == +			bw_ext_csd[EXT_CSD_PWR_CL_DDR_52_195]) && +		(card->ext_csd.raw_pwr_cl_ddr_52_360 == +			bw_ext_csd[EXT_CSD_PWR_CL_DDR_52_360]) && +		(card->ext_csd.raw_pwr_cl_ddr_200_360 == +			bw_ext_csd[EXT_CSD_PWR_CL_DDR_200_360])); + +	if (err) +		err = -EINVAL; + +out: +	mmc_free_ext_csd(bw_ext_csd);  	return err;  } @@ -335,7 +703,13 @@ MMC_DEV_ATTR(hwrev, "0x%x\n", card->cid.hwrev);  MMC_DEV_ATTR(manfid, "0x%06x\n", card->cid.manfid);  MMC_DEV_ATTR(name, "%s\n", card->cid.prod_name);  MMC_DEV_ATTR(oemid, "0x%04x\n", card->cid.oemid); +MMC_DEV_ATTR(prv, "0x%x\n", card->cid.prv);  MMC_DEV_ATTR(serial, "0x%08x\n", card->cid.serial); +MMC_DEV_ATTR(enhanced_area_offset, "%llu\n", +		card->ext_csd.enhanced_area_offset); +MMC_DEV_ATTR(enhanced_area_size, "%u\n", card->ext_csd.enhanced_area_size); +MMC_DEV_ATTR(raw_rpmb_size_mult, "%#x\n", card->ext_csd.raw_rpmb_size_mult); +MMC_DEV_ATTR(rel_sectors, "%#x\n", card->ext_csd.rel_sectors);  static struct attribute *mmc_std_attrs[] = {  	&dev_attr_cid.attr, @@ -348,22 +722,450 @@ static struct attribute *mmc_std_attrs[] = {  	&dev_attr_manfid.attr,  	&dev_attr_name.attr,  	&dev_attr_oemid.attr, +	&dev_attr_prv.attr,  	&dev_attr_serial.attr, +	&dev_attr_enhanced_area_offset.attr, +	&dev_attr_enhanced_area_size.attr, +	&dev_attr_raw_rpmb_size_mult.attr, +	&dev_attr_rel_sectors.attr,  	NULL,  }; +ATTRIBUTE_GROUPS(mmc_std); -static struct attribute_group mmc_std_attr_group = { -	.attrs = mmc_std_attrs, +static struct device_type mmc_type = { +	.groups = mmc_std_groups,  }; -static const struct attribute_group *mmc_attr_groups[] = { -	&mmc_std_attr_group, -	NULL, -}; +/* + * Select the PowerClass for the current bus width + * If power class is defined for 4/8 bit bus in the + * extended CSD register, select it by executing the + * mmc_switch command. + */ +static int __mmc_select_powerclass(struct mmc_card *card, +				   unsigned int bus_width) +{ +	struct mmc_host *host = card->host; +	struct mmc_ext_csd *ext_csd = &card->ext_csd; +	unsigned int pwrclass_val = 0; +	int err = 0; -static struct device_type mmc_type = { -	.groups = mmc_attr_groups, -}; +	/* Power class selection is supported for versions >= 4.0 */ +	if (card->csd.mmca_vsn < CSD_SPEC_VER_4) +		return 0; + +	/* Power class values are defined only for 4/8 bit bus */ +	if (bus_width == EXT_CSD_BUS_WIDTH_1) +		return 0; + +	switch (1 << host->ios.vdd) { +	case MMC_VDD_165_195: +		if (host->ios.clock <= MMC_HIGH_26_MAX_DTR) +			pwrclass_val = ext_csd->raw_pwr_cl_26_195; +		else if (host->ios.clock <= MMC_HIGH_52_MAX_DTR) +			pwrclass_val = (bus_width <= EXT_CSD_BUS_WIDTH_8) ? +				ext_csd->raw_pwr_cl_52_195 : +				ext_csd->raw_pwr_cl_ddr_52_195; +		else if (host->ios.clock <= MMC_HS200_MAX_DTR) +			pwrclass_val = ext_csd->raw_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: +	case MMC_VDD_35_36: +		if (host->ios.clock <= MMC_HIGH_26_MAX_DTR) +			pwrclass_val = ext_csd->raw_pwr_cl_26_360; +		else if (host->ios.clock <= MMC_HIGH_52_MAX_DTR) +			pwrclass_val = (bus_width <= EXT_CSD_BUS_WIDTH_8) ? +				ext_csd->raw_pwr_cl_52_360 : +				ext_csd->raw_pwr_cl_ddr_52_360; +		else if (host->ios.clock <= MMC_HS200_MAX_DTR) +			pwrclass_val = (bus_width == EXT_CSD_DDR_BUS_WIDTH_8) ? +				ext_csd->raw_pwr_cl_ddr_200_360 : +				ext_csd->raw_pwr_cl_200_360; +		break; +	default: +		pr_warning("%s: Voltage range not supported " +			   "for power class.\n", mmc_hostname(host)); +		return -EINVAL; +	} + +	if (bus_width & (EXT_CSD_BUS_WIDTH_8 | EXT_CSD_DDR_BUS_WIDTH_8)) +		pwrclass_val = (pwrclass_val & EXT_CSD_PWR_CL_8BIT_MASK) >> +				EXT_CSD_PWR_CL_8BIT_SHIFT; +	else +		pwrclass_val = (pwrclass_val & EXT_CSD_PWR_CL_4BIT_MASK) >> +				EXT_CSD_PWR_CL_4BIT_SHIFT; + +	/* If the power class is different from the default value */ +	if (pwrclass_val > 0) { +		err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, +				 EXT_CSD_POWER_CLASS, +				 pwrclass_val, +				 card->ext_csd.generic_cmd6_time); +	} + +	return err; +} + +static int mmc_select_powerclass(struct mmc_card *card) +{ +	struct mmc_host *host = card->host; +	u32 bus_width, ext_csd_bits; +	int err, ddr; + +	/* Power class selection is supported for versions >= 4.0 */ +	if (card->csd.mmca_vsn < CSD_SPEC_VER_4) +		return 0; + +	bus_width = host->ios.bus_width; +	/* Power class values are defined only for 4/8 bit bus */ +	if (bus_width == MMC_BUS_WIDTH_1) +		return 0; + +	ddr = card->mmc_avail_type & EXT_CSD_CARD_TYPE_DDR_52; +	if (ddr) +		ext_csd_bits = (bus_width == MMC_BUS_WIDTH_8) ? +			EXT_CSD_DDR_BUS_WIDTH_8 : EXT_CSD_DDR_BUS_WIDTH_4; +	else +		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); +	if (err) +		pr_warn("%s: power class selection to bus width %d ddr %d failed\n", +			mmc_hostname(host), 1 << bus_width, ddr); + +	return err; +} + +/* + * Set the bus speed for the selected speed mode. + */ +static void mmc_set_bus_speed(struct mmc_card *card) +{ +	unsigned int max_dtr = (unsigned int)-1; + +	if ((mmc_card_hs200(card) || mmc_card_hs400(card)) && +	     max_dtr > card->ext_csd.hs200_max_dtr) +		max_dtr = card->ext_csd.hs200_max_dtr; +	else if (mmc_card_hs(card) && max_dtr > card->ext_csd.hs_max_dtr) +		max_dtr = card->ext_csd.hs_max_dtr; +	else if (max_dtr > card->csd.max_dtr) +		max_dtr = card->csd.max_dtr; + +	mmc_set_clock(card->host, max_dtr); +} + +/* + * Select the bus width amoung 4-bit and 8-bit(SDR). + * If the bus width is changed successfully, return the selected width value. + * Zero is returned instead of error value if the wide width is not supported. + */ +static int mmc_select_bus_width(struct mmc_card *card) +{ +	static unsigned ext_csd_bits[] = { +		EXT_CSD_BUS_WIDTH_8, +		EXT_CSD_BUS_WIDTH_4, +	}; +	static unsigned bus_widths[] = { +		MMC_BUS_WIDTH_8, +		MMC_BUS_WIDTH_4, +	}; +	struct mmc_host *host = card->host; +	unsigned idx, bus_width = 0; +	int err = 0; + +	if ((card->csd.mmca_vsn < CSD_SPEC_VER_4) && +	    !(host->caps & (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA))) +		return 0; + +	idx = (host->caps & MMC_CAP_8_BIT_DATA) ? 0 : 1; + +	/* +	 * Unlike SD, MMC cards dont have a configuration register to notify +	 * supported bus width. So bus test command should be run to identify +	 * the supported bus width or compare the ext csd values of current +	 * bus width and ext csd values of 1 bit mode read earlier. +	 */ +	for (; idx < ARRAY_SIZE(bus_widths); idx++) { +		/* +		 * Host is capable of 8bit transfer, then switch +		 * the device to work in 8bit transfer mode. If the +		 * mmc switch command returns error then switch to +		 * 4bit transfer mode. On success set the corresponding +		 * bus width on the host. +		 */ +		err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, +				 EXT_CSD_BUS_WIDTH, +				 ext_csd_bits[idx], +				 card->ext_csd.generic_cmd6_time); +		if (err) +			continue; + +		bus_width = bus_widths[idx]; +		mmc_set_bus_width(host, bus_width); + +		/* +		 * If controller can't handle bus width test, +		 * compare ext_csd previously read in 1 bit mode +		 * against ext_csd at new bus width +		 */ +		if (!(host->caps & MMC_CAP_BUS_WIDTH_TEST)) +			err = mmc_compare_ext_csds(card, bus_width); +		else +			err = mmc_bus_test(card, bus_width); + +		if (!err) { +			err = bus_width; +			break; +		} else { +			pr_warn("%s: switch to bus width %d failed\n", +				mmc_hostname(host), ext_csd_bits[idx]); +		} +	} + +	return err; +} + +/* + * Switch to the high-speed mode + */ +static int mmc_select_hs(struct mmc_card *card) +{ +	int err; + +	err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, +			   EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS, +			   card->ext_csd.generic_cmd6_time, +			   true, true, true); +	if (!err) +		mmc_set_timing(card->host, MMC_TIMING_MMC_HS); + +	return err; +} + +/* + * Activate wide bus and DDR if supported. + */ +static int mmc_select_hs_ddr(struct mmc_card *card) +{ +	struct mmc_host *host = card->host; +	u32 bus_width, ext_csd_bits; +	int err = 0; + +	if (!(card->mmc_avail_type & EXT_CSD_CARD_TYPE_DDR_52)) +		return 0; + +	bus_width = host->ios.bus_width; +	if (bus_width == MMC_BUS_WIDTH_1) +		return 0; + +	ext_csd_bits = (bus_width == MMC_BUS_WIDTH_8) ? +		EXT_CSD_DDR_BUS_WIDTH_8 : EXT_CSD_DDR_BUS_WIDTH_4; + +	err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, +			EXT_CSD_BUS_WIDTH, +			ext_csd_bits, +			card->ext_csd.generic_cmd6_time); +	if (err) { +		pr_warn("%s: switch to bus width %d ddr failed\n", +			mmc_hostname(host), 1 << bus_width); +		return err; +	} + +	/* +	 * eMMC cards can support 3.3V to 1.2V i/o (vccq) +	 * signaling. +	 * +	 * EXT_CSD_CARD_TYPE_DDR_1_8V means 3.3V or 1.8V vccq. +	 * +	 * 1.8V vccq at 3.3V core voltage (vcc) is not required +	 * in the JEDEC spec for DDR. +	 * +	 * Do not force change in vccq since we are obviously +	 * working and no change to vccq is needed. +	 * +	 * WARNING: eMMC rules are NOT the same as SD DDR +	 */ +	if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_DDR_1_2V) { +		err = __mmc_set_signal_voltage(host, +				MMC_SIGNAL_VOLTAGE_120); +		if (err) +			return err; +	} + +	mmc_set_timing(host, MMC_TIMING_MMC_DDR52); + +	return err; +} + +static int mmc_select_hs400(struct mmc_card *card) +{ +	struct mmc_host *host = card->host; +	int err = 0; + +	/* +	 * HS400 mode requires 8-bit bus width +	 */ +	if (!(card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400 && +	      host->ios.bus_width == MMC_BUS_WIDTH_8)) +		return 0; + +	/* +	 * Before switching to dual data rate operation for HS400, +	 * it is required to convert from HS200 mode to HS mode. +	 */ +	mmc_set_timing(card->host, MMC_TIMING_MMC_HS); +	mmc_set_bus_speed(card); + +	err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, +			   EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS, +			   card->ext_csd.generic_cmd6_time, +			   true, true, true); +	if (err) { +		pr_warn("%s: switch to high-speed from hs200 failed, err:%d\n", +			mmc_hostname(host), err); +		return err; +	} + +	err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, +			 EXT_CSD_BUS_WIDTH, +			 EXT_CSD_DDR_BUS_WIDTH_8, +			 card->ext_csd.generic_cmd6_time); +	if (err) { +		pr_warn("%s: switch to bus width for hs400 failed, err:%d\n", +			mmc_hostname(host), err); +		return err; +	} + +	err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, +			   EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS400, +			   card->ext_csd.generic_cmd6_time, +			   true, true, true); +	if (err) { +		pr_warn("%s: switch to hs400 failed, err:%d\n", +			 mmc_hostname(host), err); +		return err; +	} + +	mmc_set_timing(host, MMC_TIMING_MMC_HS400); +	mmc_set_bus_speed(card); + +	return 0; +} + +/* + * For device supporting HS200 mode, the following sequence + * should be done before executing the tuning process. + * 1. set the desired bus width(4-bit or 8-bit, 1-bit is not supported) + * 2. switch to HS200 mode + * 3. set the clock to > 52Mhz and <=200MHz + */ +static int mmc_select_hs200(struct mmc_card *card) +{ +	struct mmc_host *host = card->host; +	int err = -EINVAL; + +	if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS200_1_2V) +		err = __mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_120); + +	if (err && card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS200_1_8V) +		err = __mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180); + +	/* If fails try again during next card power cycle */ +	if (err) +		goto err; + +	/* +	 * Set the bus width(4 or 8) with host's support and +	 * switch to HS200 mode if bus width is set successfully. +	 */ +	err = mmc_select_bus_width(card); +	if (!IS_ERR_VALUE(err)) { +		err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, +				   EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS200, +				   card->ext_csd.generic_cmd6_time, +				   true, true, true); +		if (!err) +			mmc_set_timing(host, MMC_TIMING_MMC_HS200); +	} +err: +	return err; +} + +/* + * Activate High Speed or HS200 mode if supported. + */ +static int mmc_select_timing(struct mmc_card *card) +{ +	int err = 0; + +	if ((card->csd.mmca_vsn < CSD_SPEC_VER_4 && +	     card->ext_csd.hs_max_dtr == 0)) +		goto bus_speed; + +	if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS200) +		err = mmc_select_hs200(card); +	else if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS) +		err = mmc_select_hs(card); + +	if (err && err != -EBADMSG) +		return err; + +	if (err) { +		pr_warn("%s: switch to %s failed\n", +			mmc_card_hs(card) ? "high-speed" : +			(mmc_card_hs200(card) ? "hs200" : ""), +			mmc_hostname(card->host)); +		err = 0; +	} + +bus_speed: +	/* +	 * Set the bus speed to the selected bus timing. +	 * If timing is not selected, backward compatible is the default. +	 */ +	mmc_set_bus_speed(card); +	return err; +} + +/* + * Execute tuning sequence to seek the proper bus operating + * conditions for HS200 and HS400, which sends CMD21 to the device. + */ +static int mmc_hs200_tuning(struct mmc_card *card) +{ +	struct mmc_host *host = card->host; +	int err = 0; + +	/* +	 * Timing should be adjusted to the HS400 target +	 * operation frequency for tuning process +	 */ +	if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400 && +	    host->ios.bus_width == MMC_BUS_WIDTH_8) +		if (host->ops->prepare_hs400_tuning) +			host->ops->prepare_hs400_tuning(host, &host->ios); + +	if (host->ops->execute_tuning) { +		mmc_host_clk_hold(host); +		err = host->ops->execute_tuning(host, +				MMC_SEND_TUNING_BLOCK_HS200); +		mmc_host_clk_release(host); + +		if (err) +			pr_warn("%s: tuning execution failed\n", +				mmc_hostname(host)); +	} + +	return err; +}  /*   * Handle the detection and initialisation of a card. @@ -375,23 +1177,29 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,  	struct mmc_card *oldcard)  {  	struct mmc_card *card; -	int err, ddr = MMC_SDR_MODE; +	int err;  	u32 cid[4]; -	unsigned int max_dtr; +	u32 rocr; +	u8 *ext_csd = NULL;  	BUG_ON(!host);  	WARN_ON(!host->claimed); +	/* Set correct bus mode for MMC before attempting init */ +	if (!mmc_host_is_spi(host)) +		mmc_set_bus_mode(host, MMC_BUSMODE_OPENDRAIN); +  	/*  	 * Since we're changing the OCR value, we seem to  	 * need to tell some cards to go back to the idle  	 * state.  We wait 1ms to give cards time to  	 * respond. +	 * mmc_go_idle is needed for eMMC that are asleep  	 */  	mmc_go_idle(host);  	/* The extra bit indicates that we support high capacity */ -	err = mmc_send_op_cond(host, ocr | (1 << 30), NULL); +	err = mmc_send_op_cond(host, ocr | (1 << 30), &rocr);  	if (err)  		goto err; @@ -431,6 +1239,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,  			goto err;  		} +		card->ocr = ocr;  		card->type = MMC_TYPE_MMC;  		card->rca = 1;  		memcpy(card->raw_cid, cid, sizeof(card->raw_cid)); @@ -476,106 +1285,274 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,  		/*  		 * Fetch and process extended CSD.  		 */ -		err = mmc_read_ext_csd(card); + +		err = mmc_get_ext_csd(card, &ext_csd); +		if (err) +			goto free_card; +		err = mmc_read_ext_csd(card, ext_csd);  		if (err)  			goto free_card; + +		/* If doing byte addressing, check if required to do sector +		 * addressing.  Handle the case of <2GB cards needing sector +		 * addressing.  See section 8.1 JEDEC Standard JED84-A441; +		 * ocr register has bit 30 set for sector addressing. +		 */ +		if (!(mmc_card_blockaddr(card)) && (rocr & (1<<30))) +			mmc_card_set_blockaddr(card); +  		/* Erase size depends on CSD and Extended CSD */  		mmc_set_erase_size(card);  	}  	/* -	 * Activate high speed (if supported) +	 * If enhanced_area_en is TRUE, host needs to enable ERASE_GRP_DEF +	 * bit.  This bit will be lost every time after a reset or power off.  	 */ -	if ((card->ext_csd.hs_max_dtr != 0) && -		(host->caps & MMC_CAP_MMC_HIGHSPEED)) { +	if (card->ext_csd.enhanced_area_en || +	    (card->ext_csd.rev >= 3 && (host->caps2 & MMC_CAP2_HC_ERASE_SZ))) {  		err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, -			EXT_CSD_HS_TIMING, 1); +				 EXT_CSD_ERASE_GROUP_DEF, 1, +				 card->ext_csd.generic_cmd6_time); +  		if (err && err != -EBADMSG)  			goto free_card;  		if (err) { -			printk(KERN_WARNING "%s: switch to highspeed failed\n", -			       mmc_hostname(card->host));  			err = 0; +			/* +			 * Just disable enhanced area off & sz +			 * will try to enable ERASE_GROUP_DEF +			 * during next time reinit +			 */ +			card->ext_csd.enhanced_area_offset = -EINVAL; +			card->ext_csd.enhanced_area_size = -EINVAL;  		} else { -			mmc_card_set_highspeed(card); -			mmc_set_timing(card->host, MMC_TIMING_MMC_HS); +			card->ext_csd.erase_group_def = 1; +			/* +			 * enable ERASE_GRP_DEF successfully. +			 * This will affect the erase size, so +			 * here need to reset erase size +			 */ +			mmc_set_erase_size(card);  		}  	}  	/* -	 * Compute bus speed. +	 * Ensure eMMC user default partition is enabled  	 */ -	max_dtr = (unsigned int)-1; +	if (card->ext_csd.part_config & EXT_CSD_PART_CONFIG_ACC_MASK) { +		card->ext_csd.part_config &= ~EXT_CSD_PART_CONFIG_ACC_MASK; +		err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONFIG, +				 card->ext_csd.part_config, +				 card->ext_csd.part_time); +		if (err && err != -EBADMSG) +			goto free_card; +	} -	if (mmc_card_highspeed(card)) { -		if (max_dtr > card->ext_csd.hs_max_dtr) -			max_dtr = card->ext_csd.hs_max_dtr; -	} else if (max_dtr > card->csd.max_dtr) { -		max_dtr = card->csd.max_dtr; +	/* +	 * Enable power_off_notification byte in the ext_csd register +	 */ +	if (card->ext_csd.rev >= 6) { +		err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, +				 EXT_CSD_POWER_OFF_NOTIFICATION, +				 EXT_CSD_POWER_ON, +				 card->ext_csd.generic_cmd6_time); +		if (err && err != -EBADMSG) +			goto free_card; + +		/* +		 * The err can be -EBADMSG or 0, +		 * so check for success and update the flag +		 */ +		if (!err) +			card->ext_csd.power_off_notification = EXT_CSD_POWER_ON; +	} + +	/* +	 * Select timing interface +	 */ +	err = mmc_select_timing(card); +	if (err) +		goto free_card; + +	if (mmc_card_hs200(card)) { +		err = mmc_hs200_tuning(card); +		if (err) +			goto err; + +		err = mmc_select_hs400(card); +		if (err) +			goto err; +	} else if (mmc_card_hs(card)) { +		/* Select the desired bus width optionally */ +		err = mmc_select_bus_width(card); +		if (!IS_ERR_VALUE(err)) { +			err = mmc_select_hs_ddr(card); +			if (err) +				goto err; +		}  	} -	mmc_set_clock(host, max_dtr); +	/* +	 * Choose the power class with selected bus interface +	 */ +	mmc_select_powerclass(card);  	/* -	 * Indicate DDR mode (if supported). +	 * Enable HPI feature (if supported)  	 */ -	if (mmc_card_highspeed(card)) { -		if ((card->ext_csd.card_type & EXT_CSD_CARD_TYPE_DDR_1_8V) -			&& (host->caps & (MMC_CAP_1_8V_DDR))) -				ddr = MMC_1_8V_DDR_MODE; -		else if ((card->ext_csd.card_type & EXT_CSD_CARD_TYPE_DDR_1_2V) -			&& (host->caps & (MMC_CAP_1_2V_DDR))) -				ddr = MMC_1_2V_DDR_MODE; +	if (card->ext_csd.hpi) { +		err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, +				EXT_CSD_HPI_MGMT, 1, +				card->ext_csd.generic_cmd6_time); +		if (err && err != -EBADMSG) +			goto free_card; +		if (err) { +			pr_warning("%s: Enabling HPI failed\n", +				   mmc_hostname(card->host)); +			err = 0; +		} else +			card->ext_csd.hpi_en = 1;  	}  	/* -	 * Activate wide bus and DDR (if supported). +	 * If cache size is higher than 0, this indicates +	 * the existence of cache and it can be turned on.  	 */ -	if ((card->csd.mmca_vsn >= CSD_SPEC_VER_4) && -	    (host->caps & (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA))) { -		unsigned ext_csd_bit, bus_width; +	if (card->ext_csd.cache_size > 0) { +		err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, +				EXT_CSD_CACHE_CTRL, 1, +				card->ext_csd.generic_cmd6_time); +		if (err && err != -EBADMSG) +			goto free_card; -		if (host->caps & MMC_CAP_8_BIT_DATA) { -			if (ddr) -				ext_csd_bit = EXT_CSD_DDR_BUS_WIDTH_8; -			else -				ext_csd_bit = EXT_CSD_BUS_WIDTH_8; -			bus_width = MMC_BUS_WIDTH_8; +		/* +		 * Only if no error, cache is turned on successfully. +		 */ +		if (err) { +			pr_warning("%s: Cache is supported, " +					"but failed to turn on (%d)\n", +					mmc_hostname(card->host), err); +			card->ext_csd.cache_ctrl = 0; +			err = 0;  		} else { -			if (ddr) -				ext_csd_bit = EXT_CSD_DDR_BUS_WIDTH_4; -			else -				ext_csd_bit = EXT_CSD_BUS_WIDTH_4; -			bus_width = MMC_BUS_WIDTH_4; +			card->ext_csd.cache_ctrl = 1;  		} +	} +	/* +	 * The mandatory minimum values are defined for packed command. +	 * read: 5, write: 3 +	 */ +	if (card->ext_csd.max_packed_writes >= 3 && +	    card->ext_csd.max_packed_reads >= 5 && +	    host->caps2 & MMC_CAP2_PACKED_CMD) {  		err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, -				 EXT_CSD_BUS_WIDTH, ext_csd_bit); - +				EXT_CSD_EXP_EVENTS_CTRL, +				EXT_CSD_PACKED_EVENT_EN, +				card->ext_csd.generic_cmd6_time);  		if (err && err != -EBADMSG)  			goto free_card; -  		if (err) { -			printk(KERN_WARNING "%s: switch to bus width %d ddr %d " -			       "failed\n", mmc_hostname(card->host), -			       1 << bus_width, ddr); +			pr_warn("%s: Enabling packed event failed\n", +				mmc_hostname(card->host)); +			card->ext_csd.packed_event_en = 0;  			err = 0;  		} else { -			mmc_card_set_ddr_mode(card); -			mmc_set_bus_width_ddr(card->host, bus_width, ddr); +			card->ext_csd.packed_event_en = 1;  		}  	}  	if (!oldcard)  		host->card = card; +	mmc_free_ext_csd(ext_csd);  	return 0;  free_card:  	if (!oldcard)  		mmc_remove_card(card);  err: +	mmc_free_ext_csd(ext_csd); + +	return err; +} + +static int mmc_can_sleep(struct mmc_card *card) +{ +	return (card && card->ext_csd.rev >= 3); +} + +static int mmc_sleep(struct mmc_host *host) +{ +	struct mmc_command cmd = {0}; +	struct mmc_card *card = host->card; +	unsigned int timeout_ms = DIV_ROUND_UP(card->ext_csd.sa_timeout, 10000); +	int err; + +	err = mmc_deselect_cards(host); +	if (err) +		return err; + +	cmd.opcode = MMC_SLEEP_AWAKE; +	cmd.arg = card->rca << 16; +	cmd.arg |= 1 << 15; + +	/* +	 * If the max_busy_timeout of the host is specified, validate it against +	 * the sleep cmd timeout. A failure means we need to prevent the host +	 * from doing hw busy detection, which is done by converting to a R1 +	 * response instead of a R1B. +	 */ +	if (host->max_busy_timeout && (timeout_ms > host->max_busy_timeout)) { +		cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; +	} else { +		cmd.flags = MMC_RSP_R1B | MMC_CMD_AC; +		cmd.busy_timeout = timeout_ms; +	} + +	err = mmc_wait_for_cmd(host, &cmd, 0); +	if (err) +		return err; + +	/* +	 * If the host does not wait while the card signals busy, then we will +	 * will have to wait the sleep/awake timeout.  Note, we cannot use the +	 * SEND_STATUS command to poll the status because that command (and most +	 * others) is invalid while the card sleeps. +	 */ +	if (!cmd.busy_timeout || !(host->caps & MMC_CAP_WAIT_WHILE_BUSY)) +		mmc_delay(timeout_ms); + +	return err; +} + +static int mmc_can_poweroff_notify(const struct mmc_card *card) +{ +	return card && +		mmc_card_mmc(card) && +		(card->ext_csd.power_off_notification == EXT_CSD_POWER_ON); +} + +static int mmc_poweroff_notify(struct mmc_card *card, unsigned int notify_type) +{ +	unsigned int timeout = card->ext_csd.generic_cmd6_time; +	int err; + +	/* Use EXT_CSD_POWER_OFF_SHORT as default notification type. */ +	if (notify_type == EXT_CSD_POWER_OFF_LONG) +		timeout = card->ext_csd.power_off_longtime; + +	err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, +			EXT_CSD_POWER_OFF_NOTIFICATION, +			notify_type, timeout, true, false, false); +	if (err) +		pr_err("%s: Power Off Notification timed out, %u\n", +		       mmc_hostname(card->host), timeout); + +	/* Disable the power off notification after the switch operation. */ +	card->ext_csd.power_off_notification = EXT_CSD_NO_POWER_NOTIFICATION;  	return err;  } @@ -593,6 +1570,14 @@ static void mmc_remove(struct mmc_host *host)  }  /* + * Card detection - card is alive. + */ +static int mmc_alive(struct mmc_host *host) +{ +	return mmc_send_status(host->card, NULL); +} + +/*   * Card detection callback from host.   */  static void mmc_detect(struct mmc_host *host) @@ -602,145 +1587,226 @@ static void mmc_detect(struct mmc_host *host)  	BUG_ON(!host);  	BUG_ON(!host->card); -	mmc_claim_host(host); +	mmc_get_card(host->card);  	/*  	 * Just check if our card has been removed.  	 */ -	err = mmc_send_status(host->card, NULL); +	err = _mmc_detect_card_removed(host); -	mmc_release_host(host); +	mmc_put_card(host->card);  	if (err) {  		mmc_remove(host);  		mmc_claim_host(host);  		mmc_detach_bus(host); +		mmc_power_off(host);  		mmc_release_host(host);  	}  } -/* - * Suspend callback from host. - */ -static int mmc_suspend(struct mmc_host *host) +static int _mmc_suspend(struct mmc_host *host, bool is_suspend)  { +	int err = 0; +	unsigned int notify_type = is_suspend ? EXT_CSD_POWER_OFF_SHORT : +					EXT_CSD_POWER_OFF_LONG; +  	BUG_ON(!host);  	BUG_ON(!host->card);  	mmc_claim_host(host); -	if (!mmc_host_is_spi(host)) -		mmc_deselect_cards(host); -	host->card->state &= ~MMC_STATE_HIGHSPEED; + +	if (mmc_card_suspended(host->card)) +		goto out; + +	if (mmc_card_doing_bkops(host->card)) { +		err = mmc_stop_bkops(host->card); +		if (err) +			goto out; +	} + +	err = mmc_flush_cache(host->card); +	if (err) +		goto out; + +	if (mmc_can_poweroff_notify(host->card) && +		((host->caps2 & MMC_CAP2_FULL_PWR_CYCLE) || !is_suspend)) +		err = mmc_poweroff_notify(host->card, notify_type); +	else if (mmc_can_sleep(host->card)) +		err = mmc_sleep(host); +	else if (!mmc_host_is_spi(host)) +		err = mmc_deselect_cards(host); + +	if (!err) { +		mmc_power_off(host); +		mmc_card_set_suspended(host->card); +	} +out:  	mmc_release_host(host); +	return err; +} -	return 0; +/* + * Suspend callback + */ +static int mmc_suspend(struct mmc_host *host) +{ +	int err; + +	err = _mmc_suspend(host, true); +	if (!err) { +		pm_runtime_disable(&host->card->dev); +		pm_runtime_set_suspended(&host->card->dev); +	} + +	return err;  }  /* - * Resume callback from host. - *   * This function tries to determine if the same card is still present   * and, if so, restore all state to it.   */ -static int mmc_resume(struct mmc_host *host) +static int _mmc_resume(struct mmc_host *host)  { -	int err; +	int err = 0;  	BUG_ON(!host);  	BUG_ON(!host->card);  	mmc_claim_host(host); -	err = mmc_init_card(host, host->ocr, host->card); -	mmc_release_host(host); +	if (!mmc_card_suspended(host->card)) +		goto out; + +	mmc_power_up(host, host->card->ocr); +	err = mmc_init_card(host, host->card->ocr, host->card); +	mmc_card_clr_suspended(host->card); + +out: +	mmc_release_host(host);  	return err;  } -static int mmc_power_restore(struct mmc_host *host) +/* + * Shutdown callback + */ +static int mmc_shutdown(struct mmc_host *host)  { -	int ret; +	int err = 0; -	host->card->state &= ~MMC_STATE_HIGHSPEED; -	mmc_claim_host(host); -	ret = mmc_init_card(host, host->ocr, host->card); -	mmc_release_host(host); +	/* +	 * In a specific case for poweroff notify, we need to resume the card +	 * before we can shutdown it properly. +	 */ +	if (mmc_can_poweroff_notify(host->card) && +		!(host->caps2 & MMC_CAP2_FULL_PWR_CYCLE)) +		err = _mmc_resume(host); -	return ret; +	if (!err) +		err = _mmc_suspend(host, false); + +	return err;  } -static int mmc_sleep(struct mmc_host *host) +/* + * Callback for resume. + */ +static int mmc_resume(struct mmc_host *host)  { -	struct mmc_card *card = host->card; -	int err = -ENOSYS; +	int err = 0; -	if (card && card->ext_csd.rev >= 3) { -		err = mmc_card_sleepawake(host, 1); -		if (err < 0) -			pr_debug("%s: Error %d while putting card into sleep", -				 mmc_hostname(host), err); +	if (!(host->caps & MMC_CAP_RUNTIME_RESUME)) { +		err = _mmc_resume(host); +		pm_runtime_set_active(&host->card->dev); +		pm_runtime_mark_last_busy(&host->card->dev);  	} +	pm_runtime_enable(&host->card->dev);  	return err;  } -static int mmc_awake(struct mmc_host *host) +/* + * Callback for runtime_suspend. + */ +static int mmc_runtime_suspend(struct mmc_host *host)  { -	struct mmc_card *card = host->card; -	int err = -ENOSYS; +	int err; -	if (card && card->ext_csd.rev >= 3) { -		err = mmc_card_sleepawake(host, 0); -		if (err < 0) -			pr_debug("%s: Error %d while awaking sleeping card", -				 mmc_hostname(host), err); -	} +	if (!(host->caps & MMC_CAP_AGGRESSIVE_PM)) +		return 0; + +	err = _mmc_suspend(host, true); +	if (err) +		pr_err("%s: error %d doing aggessive suspend\n", +			mmc_hostname(host), err);  	return err;  } -static const struct mmc_bus_ops mmc_ops = { -	.awake = mmc_awake, -	.sleep = mmc_sleep, -	.remove = mmc_remove, -	.detect = mmc_detect, -	.suspend = NULL, -	.resume = NULL, -	.power_restore = mmc_power_restore, -}; +/* + * Callback for runtime_resume. + */ +static int mmc_runtime_resume(struct mmc_host *host) +{ +	int err; -static const struct mmc_bus_ops mmc_ops_unsafe = { -	.awake = mmc_awake, -	.sleep = mmc_sleep, +	if (!(host->caps & (MMC_CAP_AGGRESSIVE_PM | MMC_CAP_RUNTIME_RESUME))) +		return 0; + +	err = _mmc_resume(host); +	if (err) +		pr_err("%s: error %d doing aggessive resume\n", +			mmc_hostname(host), err); + +	return 0; +} + +static int mmc_power_restore(struct mmc_host *host) +{ +	int ret; + +	mmc_claim_host(host); +	ret = mmc_init_card(host, host->card->ocr, host->card); +	mmc_release_host(host); + +	return ret; +} + +static const struct mmc_bus_ops mmc_ops = {  	.remove = mmc_remove,  	.detect = mmc_detect,  	.suspend = mmc_suspend,  	.resume = mmc_resume, +	.runtime_suspend = mmc_runtime_suspend, +	.runtime_resume = mmc_runtime_resume,  	.power_restore = mmc_power_restore, +	.alive = mmc_alive, +	.shutdown = mmc_shutdown,  }; -static void mmc_attach_bus_ops(struct mmc_host *host) -{ -	const struct mmc_bus_ops *bus_ops; - -	if (!mmc_card_is_removable(host)) -		bus_ops = &mmc_ops_unsafe; -	else -		bus_ops = &mmc_ops; -	mmc_attach_bus(host, bus_ops); -} -  /*   * Starting point for MMC card init.   */ -int mmc_attach_mmc(struct mmc_host *host, u32 ocr) +int mmc_attach_mmc(struct mmc_host *host)  {  	int err; +	u32 ocr, rocr;  	BUG_ON(!host);  	WARN_ON(!host->claimed); -	mmc_attach_bus_ops(host); +	/* Set correct bus mode for MMC before attempting attach */ +	if (!mmc_host_is_spi(host)) +		mmc_set_bus_mode(host, MMC_BUSMODE_OPENDRAIN); + +	err = mmc_send_op_cond(host, 0, &ocr); +	if (err) +		return err; + +	mmc_attach_bus(host, &mmc_ops); +	if (host->ocr_avail_mmc) +		host->ocr_avail = host->ocr_avail_mmc;  	/*  	 * We need to get OCR a different way for SPI. @@ -751,23 +1817,12 @@ int mmc_attach_mmc(struct mmc_host *host, u32 ocr)  			goto err;  	} -	/* -	 * Sanity check the voltages that the card claims to -	 * support. -	 */ -	if (ocr & 0x7F) { -		printk(KERN_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 of the card?  	 */ -	if (!host->ocr) { +	if (!rocr) {  		err = -EINVAL;  		goto err;  	} @@ -775,27 +1830,27 @@ int mmc_attach_mmc(struct mmc_host *host, u32 ocr)  	/*  	 * Detect and init the card.  	 */ -	err = mmc_init_card(host, host->ocr, NULL); +	err = mmc_init_card(host, rocr, NULL);  	if (err)  		goto err;  	mmc_release_host(host); -  	err = mmc_add_card(host->card); +	mmc_claim_host(host);  	if (err)  		goto remove_card;  	return 0;  remove_card: +	mmc_release_host(host);  	mmc_remove_card(host->card); -	host->card = NULL;  	mmc_claim_host(host); +	host->card = NULL;  err:  	mmc_detach_bus(host); -	mmc_release_host(host); -	printk(KERN_ERR "%s: error %d whilst initialising MMC card\n", +	pr_err("%s: error %d whilst initialising MMC card\n",  		mmc_hostname(host), err);  	return err; diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c index 326447c9ede..f51b5ba3bbe 100644 --- a/drivers/mmc/core/mmc_ops.c +++ b/drivers/mmc/core/mmc_ops.c @@ -10,6 +10,7 @@   */  #include <linux/slab.h> +#include <linux/export.h>  #include <linux/types.h>  #include <linux/scatterlist.h> @@ -20,15 +21,49 @@  #include "core.h"  #include "mmc_ops.h" +#define MMC_OPS_TIMEOUT_MS	(10 * 60 * 1000) /* 10 minute timeout */ + +static inline int __mmc_send_status(struct mmc_card *card, u32 *status, +				    bool ignore_crc) +{ +	int err; +	struct mmc_command cmd = {0}; + +	BUG_ON(!card); +	BUG_ON(!card->host); + +	cmd.opcode = MMC_SEND_STATUS; +	if (!mmc_host_is_spi(card->host)) +		cmd.arg = card->rca << 16; +	cmd.flags = MMC_RSP_SPI_R2 | MMC_RSP_R1 | MMC_CMD_AC; +	if (ignore_crc) +		cmd.flags &= ~MMC_RSP_CRC; + +	err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES); +	if (err) +		return err; + +	/* NOTE: callers are required to understand the difference +	 * between "native" and SPI format status words! +	 */ +	if (status) +		*status = cmd.resp[0]; + +	return 0; +} + +int mmc_send_status(struct mmc_card *card, u32 *status) +{ +	return __mmc_send_status(card, status, false); +} +  static int _mmc_select_card(struct mmc_host *host, struct mmc_card *card)  {  	int err; -	struct mmc_command cmd; +	struct mmc_command cmd = {0};  	BUG_ON(!host); -	memset(&cmd, 0, sizeof(struct mmc_command)); -  	cmd.opcode = MMC_SELECT_CARD;  	if (card) { @@ -58,46 +93,10 @@ int mmc_deselect_cards(struct mmc_host *host)  	return _mmc_select_card(host, NULL);  } -int mmc_card_sleepawake(struct mmc_host *host, int sleep) -{ -	struct mmc_command cmd; -	struct mmc_card *card = host->card; -	int err; - -	if (sleep) -		mmc_deselect_cards(host); - -	memset(&cmd, 0, sizeof(struct mmc_command)); - -	cmd.opcode = MMC_SLEEP_AWAKE; -	cmd.arg = card->rca << 16; -	if (sleep) -		cmd.arg |= 1 << 15; - -	cmd.flags = MMC_RSP_R1B | MMC_CMD_AC; -	err = mmc_wait_for_cmd(host, &cmd, 0); -	if (err) -		return err; - -	/* -	 * If the host does not wait while the card signals busy, then we will -	 * will have to wait the sleep/awake timeout.  Note, we cannot use the -	 * SEND_STATUS command to poll the status because that command (and most -	 * others) is invalid while the card sleeps. -	 */ -	if (!(host->caps & MMC_CAP_WAIT_WHILE_BUSY)) -		mmc_delay(DIV_ROUND_UP(card->ext_csd.sa_timeout, 10000)); - -	if (!sleep) -		err = mmc_select_card(card); - -	return err; -} -  int mmc_go_idle(struct mmc_host *host)  {  	int err; -	struct mmc_command cmd; +	struct mmc_command cmd = {0};  	/*  	 * Non-SPI hosts need to prevent chipselect going active during @@ -105,7 +104,7 @@ int mmc_go_idle(struct mmc_host *host)  	 * that in case of hardware that won't pull up DAT3/nCS otherwise.  	 *  	 * SPI hosts ignore ios.chip_select; it's managed according to -	 * rules that must accomodate non-MMC slaves which this layer +	 * rules that must accommodate non-MMC slaves which this layer  	 * won't even know about.  	 */  	if (!mmc_host_is_spi(host)) { @@ -113,8 +112,6 @@ int mmc_go_idle(struct mmc_host *host)  		mmc_delay(1);  	} -	memset(&cmd, 0, sizeof(struct mmc_command)); -  	cmd.opcode = MMC_GO_IDLE_STATE;  	cmd.arg = 0;  	cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_NONE | MMC_CMD_BC; @@ -135,13 +132,11 @@ int mmc_go_idle(struct mmc_host *host)  int mmc_send_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr)  { -	struct mmc_command cmd; +	struct mmc_command cmd = {0};  	int i, err = 0;  	BUG_ON(!host); -	memset(&cmd, 0, sizeof(struct mmc_command)); -  	cmd.opcode = MMC_SEND_OP_COND;  	cmd.arg = mmc_host_is_spi(host) ? 0 : ocr;  	cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R3 | MMC_CMD_BCR; @@ -178,13 +173,11 @@ int mmc_send_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr)  int mmc_all_send_cid(struct mmc_host *host, u32 *cid)  {  	int err; -	struct mmc_command cmd; +	struct mmc_command cmd = {0};  	BUG_ON(!host);  	BUG_ON(!cid); -	memset(&cmd, 0, sizeof(struct mmc_command)); -  	cmd.opcode = MMC_ALL_SEND_CID;  	cmd.arg = 0;  	cmd.flags = MMC_RSP_R2 | MMC_CMD_BCR; @@ -201,13 +194,11 @@ int mmc_all_send_cid(struct mmc_host *host, u32 *cid)  int mmc_set_relative_addr(struct mmc_card *card)  {  	int err; -	struct mmc_command cmd; +	struct mmc_command cmd = {0};  	BUG_ON(!card);  	BUG_ON(!card->host); -	memset(&cmd, 0, sizeof(struct mmc_command)); -  	cmd.opcode = MMC_SET_RELATIVE_ADDR;  	cmd.arg = card->rca << 16;  	cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; @@ -223,13 +214,11 @@ static int  mmc_send_cxd_native(struct mmc_host *host, u32 arg, u32 *cxd, int opcode)  {  	int err; -	struct mmc_command cmd; +	struct mmc_command cmd = {0};  	BUG_ON(!host);  	BUG_ON(!cxd); -	memset(&cmd, 0, sizeof(struct mmc_command)); -  	cmd.opcode = opcode;  	cmd.arg = arg;  	cmd.flags = MMC_RSP_R2 | MMC_CMD_AC; @@ -243,26 +232,32 @@ mmc_send_cxd_native(struct mmc_host *host, u32 arg, u32 *cxd, int opcode)  	return 0;  } +/* + * NOTE: void *buf, caller for the buf is required to use DMA-capable + * buffer or on-stack buffer (with some overhead in callee). + */  static int  mmc_send_cxd_data(struct mmc_card *card, struct mmc_host *host,  		u32 opcode, void *buf, unsigned len)  { -	struct mmc_request mrq; -	struct mmc_command cmd; -	struct mmc_data data; +	struct mmc_request mrq = {NULL}; +	struct mmc_command cmd = {0}; +	struct mmc_data data = {0};  	struct scatterlist sg;  	void *data_buf; +	int is_on_stack; -	/* dma onto stack is unsafe/nonportable, but callers to this -	 * routine normally provide temporary on-stack buffers ... -	 */ -	data_buf = kmalloc(len, GFP_KERNEL); -	if (data_buf == NULL) -		return -ENOMEM; - -	memset(&mrq, 0, sizeof(struct mmc_request)); -	memset(&cmd, 0, sizeof(struct mmc_command)); -	memset(&data, 0, sizeof(struct mmc_data)); +	is_on_stack = object_is_on_stack(buf); +	if (is_on_stack) { +		/* +		 * dma onto stack is unsafe/nonportable, but callers to this +		 * routine normally provide temporary on-stack buffers ... +		 */ +		data_buf = kmalloc(len, GFP_KERNEL); +		if (!data_buf) +			return -ENOMEM; +	} else +		data_buf = buf;  	mrq.cmd = &cmd;  	mrq.data = &data; @@ -297,8 +292,10 @@ mmc_send_cxd_data(struct mmc_card *card, struct mmc_host *host,  	mmc_wait_for_req(host, &mrq); -	memcpy(buf, data_buf, len); -	kfree(data_buf); +	if (is_on_stack) { +		memcpy(buf, data_buf, len); +		kfree(data_buf); +	}  	if (cmd.error)  		return cmd.error; @@ -311,24 +308,32 @@ mmc_send_cxd_data(struct mmc_card *card, struct mmc_host *host,  int mmc_send_csd(struct mmc_card *card, u32 *csd)  {  	int ret, i; +	u32 *csd_tmp;  	if (!mmc_host_is_spi(card->host))  		return mmc_send_cxd_native(card->host, card->rca << 16,  				csd, MMC_SEND_CSD); -	ret = mmc_send_cxd_data(card, card->host, MMC_SEND_CSD, csd, 16); +	csd_tmp = kmalloc(16, GFP_KERNEL); +	if (!csd_tmp) +		return -ENOMEM; + +	ret = mmc_send_cxd_data(card, card->host, MMC_SEND_CSD, csd_tmp, 16);  	if (ret) -		return ret; +		goto err;  	for (i = 0;i < 4;i++) -		csd[i] = be32_to_cpu(csd[i]); +		csd[i] = be32_to_cpu(csd_tmp[i]); -	return 0; +err: +	kfree(csd_tmp); +	return ret;  }  int mmc_send_cid(struct mmc_host *host, u32 *cid)  {  	int ret, i; +	u32 *cid_tmp;  	if (!mmc_host_is_spi(host)) {  		if (!host->card) @@ -337,14 +342,20 @@ int mmc_send_cid(struct mmc_host *host, u32 *cid)  				cid, MMC_SEND_CID);  	} -	ret = mmc_send_cxd_data(NULL, host, MMC_SEND_CID, cid, 16); +	cid_tmp = kmalloc(16, GFP_KERNEL); +	if (!cid_tmp) +		return -ENOMEM; + +	ret = mmc_send_cxd_data(NULL, host, MMC_SEND_CID, cid_tmp, 16);  	if (ret) -		return ret; +		goto err;  	for (i = 0;i < 4;i++) -		cid[i] = be32_to_cpu(cid[i]); +		cid[i] = be32_to_cpu(cid_tmp[i]); -	return 0; +err: +	kfree(cid_tmp); +	return ret;  }  int mmc_send_ext_csd(struct mmc_card *card, u8 *ext_csd) @@ -352,14 +363,13 @@ int mmc_send_ext_csd(struct mmc_card *card, u8 *ext_csd)  	return mmc_send_cxd_data(card, card->host, MMC_SEND_EXT_CSD,  			ext_csd, 512);  } +EXPORT_SYMBOL_GPL(mmc_send_ext_csd);  int mmc_spi_read_ocr(struct mmc_host *host, int highcap, u32 *ocrp)  { -	struct mmc_command cmd; +	struct mmc_command cmd = {0};  	int err; -	memset(&cmd, 0, sizeof(struct mmc_command)); -  	cmd.opcode = MMC_SPI_READ_OCR;  	cmd.arg = highcap ? (1 << 30) : 0;  	cmd.flags = MMC_RSP_SPI_R3; @@ -372,11 +382,9 @@ int mmc_spi_read_ocr(struct mmc_host *host, int highcap, u32 *ocrp)  int mmc_spi_set_crc(struct mmc_host *host, int use_crc)  { -	struct mmc_command cmd; +	struct mmc_command cmd = {0};  	int err; -	memset(&cmd, 0, sizeof(struct mmc_command)); -  	cmd.opcode = MMC_SPI_CRC_ON_OFF;  	cmd.flags = MMC_RSP_SPI_R1;  	cmd.arg = use_crc; @@ -387,78 +395,263 @@ int mmc_spi_set_crc(struct mmc_host *host, int use_crc)  	return err;  } -int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value) +/** + *	__mmc_switch - modify EXT_CSD register + *	@card: the MMC card associated with the data transfer + *	@set: cmd set values + *	@index: EXT_CSD register index + *	@value: value to program into EXT_CSD register + *	@timeout_ms: timeout (ms) for operation performed by register write, + *                   timeout of zero implies maximum possible timeout + *	@use_busy_signal: use the busy signal as response type + *	@send_status: send status cmd to poll for busy + *	@ignore_crc: ignore CRC errors when sending status cmd to poll for busy + * + *	Modifies the EXT_CSD register for selected card. + */ +int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value, +		unsigned int timeout_ms, bool use_busy_signal, bool send_status, +		bool ignore_crc)  { +	struct mmc_host *host = card->host;  	int err; -	struct mmc_command cmd; -	u32 status; +	struct mmc_command cmd = {0}; +	unsigned long timeout; +	u32 status = 0; +	bool use_r1b_resp = use_busy_signal; -	BUG_ON(!card); -	BUG_ON(!card->host); - -	memset(&cmd, 0, sizeof(struct mmc_command)); +	/* +	 * If the cmd timeout and the max_busy_timeout of the host are both +	 * specified, let's validate them. A failure means we need to prevent +	 * the host from doing hw busy detection, which is done by converting +	 * to a R1 response instead of a R1B. +	 */ +	if (timeout_ms && host->max_busy_timeout && +		(timeout_ms > host->max_busy_timeout)) +		use_r1b_resp = false;  	cmd.opcode = MMC_SWITCH;  	cmd.arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |  		  (index << 16) |  		  (value << 8) |  		  set; -	cmd.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC; +	cmd.flags = MMC_CMD_AC; +	if (use_r1b_resp) { +		cmd.flags |= MMC_RSP_SPI_R1B | MMC_RSP_R1B; +		/* +		 * A busy_timeout of zero means the host can decide to use +		 * whatever value it finds suitable. +		 */ +		cmd.busy_timeout = timeout_ms; +	} else { +		cmd.flags |= MMC_RSP_SPI_R1 | MMC_RSP_R1; +	} -	err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES); +	if (index == EXT_CSD_SANITIZE_START) +		cmd.sanitize_busy = true; + +	err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES);  	if (err)  		return err; -	/* Must check status to be sure of no errors */ +	/* No need to check card status in case of unblocking command */ +	if (!use_busy_signal) +		return 0; + +	/* +	 * CRC errors shall only be ignored in cases were CMD13 is used to poll +	 * to detect busy completion. +	 */ +	if ((host->caps & MMC_CAP_WAIT_WHILE_BUSY) && use_r1b_resp) +		ignore_crc = false; + +	/* We have an unspecified cmd timeout, use the fallback value. */ +	if (!timeout_ms) +		timeout_ms = MMC_OPS_TIMEOUT_MS; + +	/* Must check status to be sure of no errors. */ +	timeout = jiffies + msecs_to_jiffies(timeout_ms);  	do { -		err = mmc_send_status(card, &status); -		if (err) -			return err; -		if (card->host->caps & MMC_CAP_WAIT_WHILE_BUSY) +		if (send_status) { +			err = __mmc_send_status(card, &status, ignore_crc); +			if (err) +				return err; +		} +		if ((host->caps & MMC_CAP_WAIT_WHILE_BUSY) && use_r1b_resp)  			break; -		if (mmc_host_is_spi(card->host)) +		if (mmc_host_is_spi(host))  			break; -	} while (R1_CURRENT_STATE(status) == 7); -	if (mmc_host_is_spi(card->host)) { +		/* +		 * We are not allowed to issue a status command and the host +		 * does'nt support MMC_CAP_WAIT_WHILE_BUSY, then we can only +		 * rely on waiting for the stated timeout to be sufficient. +		 */ +		if (!send_status) { +			mmc_delay(timeout_ms); +			return 0; +		} + +		/* Timeout if the device never leaves the program state. */ +		if (time_after(jiffies, timeout)) { +			pr_err("%s: Card stuck in programming state! %s\n", +				mmc_hostname(host), __func__); +			return -ETIMEDOUT; +		} +	} while (R1_CURRENT_STATE(status) == R1_STATE_PRG); + +	if (mmc_host_is_spi(host)) {  		if (status & R1_SPI_ILLEGAL_COMMAND)  			return -EBADMSG;  	} else {  		if (status & 0xFDFFA000) -			printk(KERN_WARNING "%s: unexpected status %#x after " -			       "switch", mmc_hostname(card->host), status); +			pr_warn("%s: unexpected status %#x after switch\n", +				mmc_hostname(host), status);  		if (status & R1_SWITCH_ERROR)  			return -EBADMSG;  	}  	return 0;  } +EXPORT_SYMBOL_GPL(__mmc_switch); -int mmc_send_status(struct mmc_card *card, u32 *status) +int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value, +		unsigned int timeout_ms)  { -	int err; -	struct mmc_command cmd; +	return __mmc_switch(card, set, index, value, timeout_ms, true, true, +				false); +} +EXPORT_SYMBOL_GPL(mmc_switch); -	BUG_ON(!card); -	BUG_ON(!card->host); +static int +mmc_send_bus_test(struct mmc_card *card, struct mmc_host *host, u8 opcode, +		  u8 len) +{ +	struct mmc_request mrq = {NULL}; +	struct mmc_command cmd = {0}; +	struct mmc_data data = {0}; +	struct scatterlist sg; +	u8 *data_buf; +	u8 *test_buf; +	int i, err; +	static u8 testdata_8bit[8] = { 0x55, 0xaa, 0, 0, 0, 0, 0, 0 }; +	static u8 testdata_4bit[4] = { 0x5a, 0, 0, 0 }; -	memset(&cmd, 0, sizeof(struct mmc_command)); +	/* dma onto stack is unsafe/nonportable, but callers to this +	 * routine normally provide temporary on-stack buffers ... +	 */ +	data_buf = kmalloc(len, GFP_KERNEL); +	if (!data_buf) +		return -ENOMEM; -	cmd.opcode = MMC_SEND_STATUS; -	if (!mmc_host_is_spi(card->host)) -		cmd.arg = card->rca << 16; -	cmd.flags = MMC_RSP_SPI_R2 | MMC_RSP_R1 | MMC_CMD_AC; +	if (len == 8) +		test_buf = testdata_8bit; +	else if (len == 4) +		test_buf = testdata_4bit; +	else { +		pr_err("%s: Invalid bus_width %d\n", +		       mmc_hostname(host), len); +		kfree(data_buf); +		return -EINVAL; +	} -	err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES); -	if (err) -		return err; +	if (opcode == MMC_BUS_TEST_W) +		memcpy(data_buf, test_buf, len); -	/* NOTE: callers are required to understand the difference -	 * between "native" and SPI format status words! +	mrq.cmd = &cmd; +	mrq.data = &data; +	cmd.opcode = opcode; +	cmd.arg = 0; + +	/* NOTE HACK:  the MMC_RSP_SPI_R1 is always correct here, but we +	 * rely on callers to never use this with "native" calls for reading +	 * CSD or CID.  Native versions of those commands use the R2 type, +	 * not R1 plus a data block.  	 */ +	cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC; + +	data.blksz = len; +	data.blocks = 1; +	if (opcode == MMC_BUS_TEST_R) +		data.flags = MMC_DATA_READ; +	else +		data.flags = MMC_DATA_WRITE; + +	data.sg = &sg; +	data.sg_len = 1; +	mmc_set_data_timeout(&data, card); +	sg_init_one(&sg, data_buf, len); +	mmc_wait_for_req(host, &mrq); +	err = 0; +	if (opcode == MMC_BUS_TEST_R) { +		for (i = 0; i < len / 4; i++) +			if ((test_buf[i] ^ data_buf[i]) != 0xff) { +				err = -EIO; +				break; +			} +	} +	kfree(data_buf); + +	if (cmd.error) +		return cmd.error; +	if (data.error) +		return data.error; + +	return err; +} + +int mmc_bus_test(struct mmc_card *card, u8 bus_width) +{ +	int err, width; + +	if (bus_width == MMC_BUS_WIDTH_8) +		width = 8; +	else if (bus_width == MMC_BUS_WIDTH_4) +		width = 4; +	else if (bus_width == MMC_BUS_WIDTH_1) +		return 0; /* no need for test */ +	else +		return -EINVAL; + +	/* +	 * Ignore errors from BUS_TEST_W.  BUS_TEST_R will fail if there +	 * is a problem.  This improves chances that the test will work. +	 */ +	mmc_send_bus_test(card, card->host, MMC_BUS_TEST_W, width); +	err = mmc_send_bus_test(card, card->host, MMC_BUS_TEST_R, width); +	return err; +} + +int mmc_send_hpi_cmd(struct mmc_card *card, u32 *status) +{ +	struct mmc_command cmd = {0}; +	unsigned int opcode; +	int err; + +	if (!card->ext_csd.hpi) { +		pr_warning("%s: Card didn't support HPI command\n", +			   mmc_hostname(card->host)); +		return -EINVAL; +	} + +	opcode = card->ext_csd.hpi_cmd; +	if (opcode == MMC_STOP_TRANSMISSION) +		cmd.flags = MMC_RSP_R1B | MMC_CMD_AC; +	else if (opcode == MMC_SEND_STATUS) +		cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; + +	cmd.opcode = opcode; +	cmd.arg = card->rca << 16 | 1; + +	err = mmc_wait_for_cmd(card->host, &cmd, 0); +	if (err) { +		pr_warn("%s: error %d interrupting operation. " +			"HPI command response %#x\n", mmc_hostname(card->host), +			err, cmd.resp[0]); +		return err; +	}  	if (status)  		*status = cmd.resp[0];  	return 0;  } - diff --git a/drivers/mmc/core/mmc_ops.h b/drivers/mmc/core/mmc_ops.h index 653eb8e8417..80ae9f4e029 100644 --- a/drivers/mmc/core/mmc_ops.h +++ b/drivers/mmc/core/mmc_ops.h @@ -20,12 +20,12 @@ int mmc_all_send_cid(struct mmc_host *host, u32 *cid);  int mmc_set_relative_addr(struct mmc_card *card);  int mmc_send_csd(struct mmc_card *card, u32 *csd);  int mmc_send_ext_csd(struct mmc_card *card, u8 *ext_csd); -int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value);  int mmc_send_status(struct mmc_card *card, u32 *status);  int mmc_send_cid(struct mmc_host *host, u32 *cid);  int mmc_spi_read_ocr(struct mmc_host *host, int highcap, u32 *ocrp);  int mmc_spi_set_crc(struct mmc_host *host, int use_crc); -int mmc_card_sleepawake(struct mmc_host *host, int sleep); +int mmc_bus_test(struct mmc_card *card, u8 bus_width); +int mmc_send_hpi_cmd(struct mmc_card *card, u32 *status);  #endif diff --git a/drivers/mmc/core/quirks.c b/drivers/mmc/core/quirks.c new file mode 100644 index 00000000000..6c36fccaa1e --- /dev/null +++ b/drivers/mmc/core/quirks.c @@ -0,0 +1,99 @@ +/* + *  This file contains work-arounds for many known SD/MMC + *  and SDIO hardware bugs. + * + *  Copyright (c) 2011 Andrei Warkentin <andreiw@motorola.com> + *  Copyright (c) 2011 Pierre Tardy <tardyp@gmail.com> + *  Inspired from pci fixup code: + *  Copyright (c) 1999 Martin Mares <mj@ucw.cz> + * + */ + +#include <linux/types.h> +#include <linux/kernel.h> +#include <linux/export.h> +#include <linux/mmc/card.h> +#include <linux/mmc/sdio_ids.h> + +#ifndef SDIO_VENDOR_ID_TI +#define SDIO_VENDOR_ID_TI		0x0097 +#endif + +#ifndef SDIO_DEVICE_ID_TI_WL1271 +#define SDIO_DEVICE_ID_TI_WL1271	0x4076 +#endif + +#ifndef SDIO_VENDOR_ID_STE +#define SDIO_VENDOR_ID_STE		0x0020 +#endif + +#ifndef SDIO_DEVICE_ID_STE_CW1200 +#define SDIO_DEVICE_ID_STE_CW1200	0x2280 +#endif + +#ifndef SDIO_DEVICE_ID_MARVELL_8797_F0 +#define SDIO_DEVICE_ID_MARVELL_8797_F0	0x9128 +#endif + +/* + * This hook just adds a quirk for all sdio devices + */ +static void add_quirk_for_sdio_devices(struct mmc_card *card, int data) +{ +	if (mmc_card_sdio(card)) +		card->quirks |= data; +} + +static const struct mmc_fixup mmc_fixup_methods[] = { +	/* by default sdio devices are considered CLK_GATING broken */ +	/* good cards will be whitelisted as they are tested */ +	SDIO_FIXUP(SDIO_ANY_ID, SDIO_ANY_ID, +		   add_quirk_for_sdio_devices, +		   MMC_QUIRK_BROKEN_CLK_GATING), + +	SDIO_FIXUP(SDIO_VENDOR_ID_TI, SDIO_DEVICE_ID_TI_WL1271, +		   remove_quirk, MMC_QUIRK_BROKEN_CLK_GATING), + +	SDIO_FIXUP(SDIO_VENDOR_ID_TI, SDIO_DEVICE_ID_TI_WL1271, +		   add_quirk, MMC_QUIRK_NONSTD_FUNC_IF), + +	SDIO_FIXUP(SDIO_VENDOR_ID_TI, SDIO_DEVICE_ID_TI_WL1271, +		   add_quirk, MMC_QUIRK_DISABLE_CD), + +	SDIO_FIXUP(SDIO_VENDOR_ID_STE, SDIO_DEVICE_ID_STE_CW1200, +		   add_quirk, MMC_QUIRK_BROKEN_BYTE_MODE_512), + +	SDIO_FIXUP(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8797_F0, +		   add_quirk, MMC_QUIRK_BROKEN_IRQ_POLLING), + +	END_FIXUP +}; + +void mmc_fixup_device(struct mmc_card *card, const struct mmc_fixup *table) +{ +	const struct mmc_fixup *f; +	u64 rev = cid_rev_card(card); + +	/* Non-core specific workarounds. */ +	if (!table) +		table = mmc_fixup_methods; + +	for (f = table; f->vendor_fixup; f++) { +		if ((f->manfid == CID_MANFID_ANY || +		     f->manfid == card->cid.manfid) && +		    (f->oemid == CID_OEMID_ANY || +		     f->oemid == card->cid.oemid) && +		    (f->name == CID_NAME_ANY || +		     !strncmp(f->name, card->cid.prod_name, +			      sizeof(card->cid.prod_name))) && +		    (f->cis_vendor == card->cis.vendor || +		     f->cis_vendor == (u16) SDIO_ANY_ID) && +		    (f->cis_device == card->cis.device || +		     f->cis_device == (u16) SDIO_ANY_ID) && +		    rev >= f->rev_start && rev <= f->rev_end) { +			dev_dbg(&card->dev, "calling %pF\n", f->vendor_fixup); +			f->vendor_fixup(card, f->data); +		} +	} +} +EXPORT_SYMBOL(mmc_fixup_device); diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index 49da4dffd28..0c44510bf71 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c @@ -11,7 +11,10 @@   */  #include <linux/err.h> +#include <linux/sizes.h>  #include <linux/slab.h> +#include <linux/stat.h> +#include <linux/pm_runtime.h>  #include <linux/mmc/host.h>  #include <linux/mmc/card.h> @@ -21,6 +24,7 @@  #include "core.h"  #include "bus.h"  #include "mmc_ops.h" +#include "sd.h"  #include "sd_ops.h"  static const unsigned int tran_exp[] = { @@ -42,6 +46,13 @@ static const unsigned int tacc_mant[] = {  	35,	40,	45,	50,	55,	60,	70,	80,  }; +static const unsigned int sd_au_size[] = { +	0,		SZ_16K / 512,		SZ_32K / 512,	SZ_64K / 512, +	SZ_128K / 512,	SZ_256K / 512,		SZ_512K / 512,	SZ_1M / 512, +	SZ_2M / 512,	SZ_4M / 512,		SZ_8M / 512,	(SZ_8M + SZ_4M) / 512, +	SZ_16M / 512,	(SZ_16M + SZ_8M) / 512,	SZ_32M / 512,	SZ_64M / 512, +}; +  #define UNSTUFF_BITS(resp,start,size)					\  	({								\  		const int __size = size;				\ @@ -129,7 +140,7 @@ static int mmc_decode_csd(struct mmc_card *card)  		break;  	case 1:  		/* -		 * This is a block-addressed SDHC card. Most +		 * This is a block-addressed SDHC or SDXC card. Most  		 * interesting fields are unused and have fixed  		 * values. To avoid getting tripped by buggy cards,  		 * we assume those fixed values ourselves. @@ -143,6 +154,11 @@ static int mmc_decode_csd(struct mmc_card *card)  		e = UNSTUFF_BITS(resp, 96, 3);  		csd->max_dtr	  = tran_exp[e] * tran_mant[m];  		csd->cmdclass	  = UNSTUFF_BITS(resp, 84, 12); +		csd->c_size	  = UNSTUFF_BITS(resp, 48, 22); + +		/* SDXC cards have a minimum C_SIZE of 0x00FFFF */ +		if (csd->c_size >= 0xFFFF) +			mmc_card_set_ext_capacity(card);  		m = UNSTUFF_BITS(resp, 48, 22);  		csd->capacity     = (1 + m) << 10; @@ -157,7 +173,7 @@ static int mmc_decode_csd(struct mmc_card *card)  		csd->erase_size = 1;  		break;  	default: -		printk(KERN_ERR "%s: unrecognised CSD structure version %d\n", +		pr_err("%s: unrecognised CSD structure version %d\n",  			mmc_hostname(card->host), csd_struct);  		return -EINVAL;  	} @@ -181,19 +197,24 @@ static int mmc_decode_scr(struct mmc_card *card)  	scr_struct = UNSTUFF_BITS(resp, 60, 4);  	if (scr_struct != 0) { -		printk(KERN_ERR "%s: unrecognised SCR structure version %d\n", +		pr_err("%s: unrecognised SCR structure version %d\n",  			mmc_hostname(card->host), scr_struct);  		return -EINVAL;  	}  	scr->sda_vsn = UNSTUFF_BITS(resp, 56, 4);  	scr->bus_widths = UNSTUFF_BITS(resp, 48, 4); +	if (scr->sda_vsn == SCR_SPEC_VER_2) +		/* Check if Physical Layer Spec v3.0 is supported */ +		scr->sda_spec3 = UNSTUFF_BITS(resp, 47, 1);  	if (UNSTUFF_BITS(resp, 55, 1))  		card->erased_byte = 0xFF;  	else  		card->erased_byte = 0x0; +	if (scr->sda_spec3) +		scr->cmds = UNSTUFF_BITS(resp, 32, 2);  	return 0;  } @@ -207,7 +228,7 @@ static int mmc_read_ssr(struct mmc_card *card)  	u32 *ssr;  	if (!(card->csd.cmdclass & CCC_APP_SPEC)) { -		printk(KERN_WARNING "%s: card lacks mandatory SD Status " +		pr_warning("%s: card lacks mandatory SD Status "  			"function.\n", mmc_hostname(card->host));  		return 0;  	} @@ -218,7 +239,7 @@ static int mmc_read_ssr(struct mmc_card *card)  	err = mmc_app_sd_status(card, ssr);  	if (err) { -		printk(KERN_WARNING "%s: problem reading SD Status " +		pr_warning("%s: problem reading SD Status "  			"register.\n", mmc_hostname(card->host));  		err = 0;  		goto out; @@ -232,18 +253,20 @@ static int mmc_read_ssr(struct mmc_card *card)  	 * bitfield positions accordingly.  	 */  	au = UNSTUFF_BITS(ssr, 428 - 384, 4); -	if (au > 0 || au <= 9) { -		card->ssr.au = 1 << (au + 4); -		es = UNSTUFF_BITS(ssr, 408 - 384, 16); -		et = UNSTUFF_BITS(ssr, 402 - 384, 6); -		eo = UNSTUFF_BITS(ssr, 400 - 384, 2); -		if (es && et) { -			card->ssr.erase_timeout = (et * 1000) / es; -			card->ssr.erase_offset = eo * 1000; +	if (au) { +		if (au <= 9 || card->scr.sda_spec3) { +			card->ssr.au = sd_au_size[au]; +			es = UNSTUFF_BITS(ssr, 408 - 384, 16); +			et = UNSTUFF_BITS(ssr, 402 - 384, 6); +			if (es && et) { +				eo = UNSTUFF_BITS(ssr, 400 - 384, 2); +				card->ssr.erase_timeout = (et * 1000) / es; +				card->ssr.erase_offset = eo * 1000; +			} +		} else { +			pr_warning("%s: SD Status: Invalid Allocation Unit size.\n", +				   mmc_hostname(card->host));  		} -	} else { -		printk(KERN_WARNING "%s: SD Status: Invalid Allocation Unit " -			"size.\n", mmc_hostname(card->host));  	}  out:  	kfree(ssr); @@ -262,7 +285,7 @@ static int mmc_read_switch(struct mmc_card *card)  		return 0;  	if (!(card->csd.cmdclass & CCC_SWITCH)) { -		printk(KERN_WARNING "%s: card lacks mandatory switch " +		pr_warning("%s: card lacks mandatory switch "  			"function, performance might suffer.\n",  			mmc_hostname(card->host));  		return 0; @@ -272,30 +295,41 @@ static int mmc_read_switch(struct mmc_card *card)  	status = kmalloc(64, GFP_KERNEL);  	if (!status) { -		printk(KERN_ERR "%s: could not allocate a buffer for " -			"switch capabilities.\n", mmc_hostname(card->host)); +		pr_err("%s: could not allocate a buffer for " +			"switch capabilities.\n", +			mmc_hostname(card->host));  		return -ENOMEM;  	} -	err = mmc_sd_switch(card, 0, 0, 1, status); +	/* +	 * Find out the card's support bits with a mode 0 operation. +	 * The argument does not matter, as the support bits do not +	 * change with the arguments. +	 */ +	err = mmc_sd_switch(card, 0, 0, 0, status);  	if (err) { -		/* If the host or the card can't do the switch, -		 * fail more gracefully. */ -		if ((err != -EINVAL) -		 && (err != -ENOSYS) -		 && (err != -EFAULT)) +		/* +		 * If the host or the card can't do the switch, +		 * fail more gracefully. +		 */ +		if (err != -EINVAL && err != -ENOSYS && err != -EFAULT)  			goto out; -		printk(KERN_WARNING "%s: problem reading switch " -			"capabilities, performance might suffer.\n", +		pr_warning("%s: problem reading Bus Speed modes.\n",  			mmc_hostname(card->host));  		err = 0;  		goto out;  	} -	if (status[13] & 0x02) -		card->sw_caps.hs_max_dtr = 50000000; +	if (status[13] & SD_MODE_HIGH_SPEED) +		card->sw_caps.hs_max_dtr = HIGH_SPEED_MAX_DTR; + +	if (card->scr.sda_spec3) { +		card->sw_caps.sd3_bus_mode = status[13]; +		/* Driver Strengths supported by the card */ +		card->sw_caps.sd3_drv_type = status[9]; +	}  out:  	kfree(status); @@ -327,7 +361,7 @@ int mmc_sd_switch_hs(struct mmc_card *card)  	status = kmalloc(64, GFP_KERNEL);  	if (!status) { -		printk(KERN_ERR "%s: could not allocate a buffer for " +		pr_err("%s: could not allocate a buffer for "  			"switch capabilities.\n", mmc_hostname(card->host));  		return -ENOMEM;  	} @@ -337,7 +371,7 @@ int mmc_sd_switch_hs(struct mmc_card *card)  		goto out;  	if ((status[16] & 0xF) != 1) { -		printk(KERN_WARNING "%s: Problem switching card " +		pr_warning("%s: Problem switching card "  			"into high-speed mode!\n",  			mmc_hostname(card->host));  		err = 0; @@ -351,6 +385,297 @@ out:  	return err;  } +static int sd_select_driver_type(struct mmc_card *card, u8 *status) +{ +	int host_drv_type = SD_DRIVER_TYPE_B; +	int card_drv_type = SD_DRIVER_TYPE_B; +	int drive_strength; +	int err; + +	/* +	 * If the host doesn't support any of the Driver Types A,C or D, +	 * or there is no board specific handler then default Driver +	 * Type B is used. +	 */ +	if (!(card->host->caps & (MMC_CAP_DRIVER_TYPE_A | MMC_CAP_DRIVER_TYPE_C +	    | MMC_CAP_DRIVER_TYPE_D))) +		return 0; + +	if (!card->host->ops->select_drive_strength) +		return 0; + +	if (card->host->caps & MMC_CAP_DRIVER_TYPE_A) +		host_drv_type |= SD_DRIVER_TYPE_A; + +	if (card->host->caps & MMC_CAP_DRIVER_TYPE_C) +		host_drv_type |= SD_DRIVER_TYPE_C; + +	if (card->host->caps & MMC_CAP_DRIVER_TYPE_D) +		host_drv_type |= SD_DRIVER_TYPE_D; + +	if (card->sw_caps.sd3_drv_type & SD_DRIVER_TYPE_A) +		card_drv_type |= SD_DRIVER_TYPE_A; + +	if (card->sw_caps.sd3_drv_type & SD_DRIVER_TYPE_C) +		card_drv_type |= SD_DRIVER_TYPE_C; + +	if (card->sw_caps.sd3_drv_type & SD_DRIVER_TYPE_D) +		card_drv_type |= SD_DRIVER_TYPE_D; + +	/* +	 * The drive strength that the hardware can support +	 * depends on the board design.  Pass the appropriate +	 * information and let the hardware specific code +	 * return what is possible given the options +	 */ +	mmc_host_clk_hold(card->host); +	drive_strength = card->host->ops->select_drive_strength( +		card->sw_caps.uhs_max_dtr, +		host_drv_type, card_drv_type); +	mmc_host_clk_release(card->host); + +	err = mmc_sd_switch(card, 1, 2, drive_strength, status); +	if (err) +		return err; + +	if ((status[15] & 0xF) != drive_strength) { +		pr_warning("%s: Problem setting drive strength!\n", +			mmc_hostname(card->host)); +		return 0; +	} + +	mmc_set_driver_type(card->host, drive_strength); + +	return 0; +} + +static void sd_update_bus_speed_mode(struct mmc_card *card) +{ +	/* +	 * If the host doesn't support any of the UHS-I modes, fallback on +	 * default speed. +	 */ +	if (!mmc_host_uhs(card->host)) { +		card->sd_bus_speed = 0; +		return; +	} + +	if ((card->host->caps & MMC_CAP_UHS_SDR104) && +	    (card->sw_caps.sd3_bus_mode & SD_MODE_UHS_SDR104)) { +			card->sd_bus_speed = UHS_SDR104_BUS_SPEED; +	} else if ((card->host->caps & MMC_CAP_UHS_DDR50) && +		   (card->sw_caps.sd3_bus_mode & SD_MODE_UHS_DDR50)) { +			card->sd_bus_speed = UHS_DDR50_BUS_SPEED; +	} else if ((card->host->caps & (MMC_CAP_UHS_SDR104 | +		    MMC_CAP_UHS_SDR50)) && (card->sw_caps.sd3_bus_mode & +		    SD_MODE_UHS_SDR50)) { +			card->sd_bus_speed = UHS_SDR50_BUS_SPEED; +	} else if ((card->host->caps & (MMC_CAP_UHS_SDR104 | +		    MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR25)) && +		   (card->sw_caps.sd3_bus_mode & SD_MODE_UHS_SDR25)) { +			card->sd_bus_speed = UHS_SDR25_BUS_SPEED; +	} else if ((card->host->caps & (MMC_CAP_UHS_SDR104 | +		    MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR25 | +		    MMC_CAP_UHS_SDR12)) && (card->sw_caps.sd3_bus_mode & +		    SD_MODE_UHS_SDR12)) { +			card->sd_bus_speed = UHS_SDR12_BUS_SPEED; +	} +} + +static int sd_set_bus_speed_mode(struct mmc_card *card, u8 *status) +{ +	int err; +	unsigned int timing = 0; + +	switch (card->sd_bus_speed) { +	case UHS_SDR104_BUS_SPEED: +		timing = MMC_TIMING_UHS_SDR104; +		card->sw_caps.uhs_max_dtr = UHS_SDR104_MAX_DTR; +		break; +	case UHS_DDR50_BUS_SPEED: +		timing = MMC_TIMING_UHS_DDR50; +		card->sw_caps.uhs_max_dtr = UHS_DDR50_MAX_DTR; +		break; +	case UHS_SDR50_BUS_SPEED: +		timing = MMC_TIMING_UHS_SDR50; +		card->sw_caps.uhs_max_dtr = UHS_SDR50_MAX_DTR; +		break; +	case UHS_SDR25_BUS_SPEED: +		timing = MMC_TIMING_UHS_SDR25; +		card->sw_caps.uhs_max_dtr = UHS_SDR25_MAX_DTR; +		break; +	case UHS_SDR12_BUS_SPEED: +		timing = MMC_TIMING_UHS_SDR12; +		card->sw_caps.uhs_max_dtr = UHS_SDR12_MAX_DTR; +		break; +	default: +		return 0; +	} + +	err = mmc_sd_switch(card, 1, 0, card->sd_bus_speed, status); +	if (err) +		return err; + +	if ((status[16] & 0xF) != card->sd_bus_speed) +		pr_warning("%s: Problem setting bus speed mode!\n", +			mmc_hostname(card->host)); +	else { +		mmc_set_timing(card->host, timing); +		mmc_set_clock(card->host, card->sw_caps.uhs_max_dtr); +	} + +	return 0; +} + +/* Get host's max current setting at its current voltage */ +static u32 sd_get_host_max_current(struct mmc_host *host) +{ +	u32 voltage, max_current; + +	voltage = 1 << host->ios.vdd; +	switch (voltage) { +	case MMC_VDD_165_195: +		max_current = host->max_current_180; +		break; +	case MMC_VDD_29_30: +	case MMC_VDD_30_31: +		max_current = host->max_current_300; +		break; +	case MMC_VDD_32_33: +	case MMC_VDD_33_34: +		max_current = host->max_current_330; +		break; +	default: +		max_current = 0; +	} + +	return max_current; +} + +static int sd_set_current_limit(struct mmc_card *card, u8 *status) +{ +	int current_limit = SD_SET_CURRENT_NO_CHANGE; +	int err; +	u32 max_current; + +	/* +	 * Current limit switch is only defined for SDR50, SDR104, and DDR50 +	 * bus speed modes. For other bus speed modes, we do not change the +	 * current limit. +	 */ +	if ((card->sd_bus_speed != UHS_SDR50_BUS_SPEED) && +	    (card->sd_bus_speed != UHS_SDR104_BUS_SPEED) && +	    (card->sd_bus_speed != UHS_DDR50_BUS_SPEED)) +		return 0; + +	/* +	 * Host has different current capabilities when operating at +	 * different voltages, so find out its max current first. +	 */ +	max_current = sd_get_host_max_current(card->host); + +	/* +	 * We only check host's capability here, if we set a limit that is +	 * higher than the card's maximum current, the card will be using its +	 * maximum current, e.g. if the card's maximum current is 300ma, and +	 * when we set current limit to 200ma, the card will draw 200ma, and +	 * when we set current limit to 400/600/800ma, the card will draw its +	 * maximum 300ma from the host. +	 */ +	if (max_current >= 800) +		current_limit = SD_SET_CURRENT_LIMIT_800; +	else if (max_current >= 600) +		current_limit = SD_SET_CURRENT_LIMIT_600; +	else if (max_current >= 400) +		current_limit = SD_SET_CURRENT_LIMIT_400; +	else if (max_current >= 200) +		current_limit = SD_SET_CURRENT_LIMIT_200; + +	if (current_limit != SD_SET_CURRENT_NO_CHANGE) { +		err = mmc_sd_switch(card, 1, 3, current_limit, status); +		if (err) +			return err; + +		if (((status[15] >> 4) & 0x0F) != current_limit) +			pr_warning("%s: Problem setting current limit!\n", +				mmc_hostname(card->host)); + +	} + +	return 0; +} + +/* + * UHS-I specific initialization procedure + */ +static int mmc_sd_init_uhs_card(struct mmc_card *card) +{ +	int err; +	u8 *status; + +	if (!card->scr.sda_spec3) +		return 0; + +	if (!(card->csd.cmdclass & CCC_SWITCH)) +		return 0; + +	status = kmalloc(64, GFP_KERNEL); +	if (!status) { +		pr_err("%s: could not allocate a buffer for " +			"switch capabilities.\n", mmc_hostname(card->host)); +		return -ENOMEM; +	} + +	/* Set 4-bit bus width */ +	if ((card->host->caps & MMC_CAP_4_BIT_DATA) && +	    (card->scr.bus_widths & SD_SCR_BUS_WIDTH_4)) { +		err = mmc_app_set_bus_width(card, MMC_BUS_WIDTH_4); +		if (err) +			goto out; + +		mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4); +	} + +	/* +	 * Select the bus speed mode depending on host +	 * and card capability. +	 */ +	sd_update_bus_speed_mode(card); + +	/* Set the driver strength for the card */ +	err = sd_select_driver_type(card, status); +	if (err) +		goto out; + +	/* Set current limit for the card */ +	err = sd_set_current_limit(card, status); +	if (err) +		goto out; + +	/* Set bus speed mode of the card */ +	err = sd_set_bus_speed_mode(card, status); +	if (err) +		goto out; + +	/* +	 * SPI mode doesn't define CMD19 and tuning is only valid for SDR50 and +	 * SDR104 mode SD-cards. Note that tuning is mandatory for SDR104. +	 */ +	if (!mmc_host_is_spi(card->host) && card->host->ops->execute_tuning && +			(card->sd_bus_speed == UHS_SDR50_BUS_SPEED || +			 card->sd_bus_speed == UHS_SDR104_BUS_SPEED)) { +		mmc_host_clk_hold(card->host); +		err = card->host->ops->execute_tuning(card->host, +						      MMC_SEND_TUNING_BLOCK); +		mmc_host_clk_release(card->host); +	} + +out: +	kfree(status); + +	return err; +} +  MMC_DEV_ATTR(cid, "%08x%08x%08x%08x\n", card->raw_cid[0], card->raw_cid[1],  	card->raw_cid[2], card->raw_cid[3]);  MMC_DEV_ATTR(csd, "%08x%08x%08x%08x\n", card->raw_csd[0], card->raw_csd[1], @@ -382,26 +707,28 @@ static struct attribute *sd_std_attrs[] = {  	&dev_attr_serial.attr,  	NULL,  }; - -static struct attribute_group sd_std_attr_group = { -	.attrs = sd_std_attrs, -}; - -static const struct attribute_group *sd_attr_groups[] = { -	&sd_std_attr_group, -	NULL, -}; +ATTRIBUTE_GROUPS(sd_std);  struct device_type sd_type = { -	.groups = sd_attr_groups, +	.groups = sd_std_groups,  };  /*   * Fetch CID from card.   */ -int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid) +int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid, u32 *rocr)  {  	int err; +	u32 max_current; +	int retries = 10; +	u32 pocr = ocr; + +try_again: +	if (!retries) { +		ocr &= ~SD_OCR_S18R; +		pr_warning("%s: Skipping voltage switch\n", +			mmc_hostname(host)); +	}  	/*  	 * Since we're changing the OCR value, we seem to @@ -419,12 +746,45 @@ int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid)  	 */  	err = mmc_send_if_cond(host, ocr);  	if (!err) -		ocr |= 1 << 30; +		ocr |= SD_OCR_CCS; + +	/* +	 * If the host supports one of UHS-I modes, request the card +	 * to switch to 1.8V signaling level. If the card has failed +	 * repeatedly to switch however, skip this. +	 */ +	if (retries && mmc_host_uhs(host)) +		ocr |= SD_OCR_S18R; -	err = mmc_send_app_op_cond(host, ocr, NULL); +	/* +	 * If the host can supply more than 150mA at current voltage, +	 * XPC should be set to 1. +	 */ +	max_current = sd_get_host_max_current(host); +	if (max_current > 150) +		ocr |= SD_OCR_XPC; + +	err = mmc_send_app_op_cond(host, ocr, rocr);  	if (err)  		return err; +	/* +	 * In case CCS and S18A in the response is set, start Signal Voltage +	 * Switch procedure. SPI mode doesn't support CMD11. +	 */ +	if (!mmc_host_is_spi(host) && rocr && +	   ((*rocr & 0x41000000) == 0x41000000)) { +		err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180, +					pocr); +		if (err == -EAGAIN) { +			retries--; +			goto try_again; +		} else if (err) { +			retries = 0; +			goto try_again; +		} +	} +  	if (mmc_host_is_spi(host))  		err = mmc_send_cid(host, cid);  	else @@ -504,11 +864,14 @@ int mmc_sd_setup_card(struct mmc_host *host, struct mmc_card *card,  	if (!reinit) {  		int ro = -1; -		if (host->ops->get_ro) +		if (host->ops->get_ro) { +			mmc_host_clk_hold(card->host);  			ro = host->ops->get_ro(host); +			mmc_host_clk_release(card->host); +		}  		if (ro < 0) { -			printk(KERN_WARNING "%s: host does not " +			pr_warning("%s: host does not "  				"support reading read-only "  				"switch. assuming write-enable.\n",  				mmc_hostname(host)); @@ -524,7 +887,7 @@ unsigned mmc_sd_get_max_clock(struct mmc_card *card)  {  	unsigned max_dtr = (unsigned int)-1; -	if (mmc_card_highspeed(card)) { +	if (mmc_card_hs(card)) {  		if (max_dtr > card->sw_caps.hs_max_dtr)  			max_dtr = card->sw_caps.hs_max_dtr;  	} else if (max_dtr > card->csd.max_dtr) { @@ -534,12 +897,6 @@ unsigned mmc_sd_get_max_clock(struct mmc_card *card)  	return max_dtr;  } -void mmc_sd_go_highspeed(struct mmc_card *card) -{ -	mmc_card_set_highspeed(card); -	mmc_set_timing(card->host, MMC_TIMING_SD_HS); -} -  /*   * Handle the detection and initialisation of a card.   * @@ -552,11 +909,12 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,  	struct mmc_card *card;  	int err;  	u32 cid[4]; +	u32 rocr = 0;  	BUG_ON(!host);  	WARN_ON(!host->claimed); -	err = mmc_sd_get_cid(host, ocr, cid); +	err = mmc_sd_get_cid(host, ocr, cid, &rocr);  	if (err)  		return err; @@ -573,6 +931,7 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,  		if (IS_ERR(card))  			return PTR_ERR(card); +		card->ocr = ocr;  		card->type = MMC_TYPE_SD;  		memcpy(card->raw_cid, cid, sizeof(card->raw_cid));  	} @@ -583,15 +942,13 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,  	if (!mmc_host_is_spi(host)) {  		err = mmc_send_relative_addr(host, &card->rca);  		if (err) -			return err; - -		mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL); +			goto free_card;  	}  	if (!oldcard) {  		err = mmc_sd_get_csd(host, card);  		if (err) -			return err; +			goto free_card;  		mmc_decode_cid(card);  	} @@ -602,37 +959,44 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,  	if (!mmc_host_is_spi(host)) {  		err = mmc_select_card(card);  		if (err) -			return err; +			goto free_card;  	}  	err = mmc_sd_setup_card(host, card, oldcard != NULL);  	if (err)  		goto free_card; -	/* -	 * Attempt to change to high-speed (if supported) -	 */ -	err = mmc_sd_switch_hs(card); -	if (err > 0) -		mmc_sd_go_highspeed(card); -	else if (err) -		goto free_card; - -	/* -	 * Set bus speed. -	 */ -	mmc_set_clock(host, mmc_sd_get_max_clock(card)); - -	/* -	 * Switch to wider bus (if supported). -	 */ -	if ((host->caps & MMC_CAP_4_BIT_DATA) && -		(card->scr.bus_widths & SD_SCR_BUS_WIDTH_4)) { -		err = mmc_app_set_bus_width(card, MMC_BUS_WIDTH_4); +	/* Initialization sequence for UHS-I cards */ +	if (rocr & SD_ROCR_S18A) { +		err = mmc_sd_init_uhs_card(card);  		if (err)  			goto free_card; +	} else { +		/* +		 * Attempt to change to high-speed (if supported) +		 */ +		err = mmc_sd_switch_hs(card); +		if (err > 0) +			mmc_set_timing(card->host, MMC_TIMING_SD_HS); +		else if (err) +			goto free_card; + +		/* +		 * Set bus speed. +		 */ +		mmc_set_clock(host, mmc_sd_get_max_clock(card)); -		mmc_set_bus_width(host, MMC_BUS_WIDTH_4); +		/* +		 * Switch to wider bus (if supported). +		 */ +		if ((host->caps & MMC_CAP_4_BIT_DATA) && +			(card->scr.bus_widths & SD_SCR_BUS_WIDTH_4)) { +			err = mmc_app_set_bus_width(card, MMC_BUS_WIDTH_4); +			if (err) +				goto free_card; + +			mmc_set_bus_width(host, MMC_BUS_WIDTH_4); +		}  	}  	host->card = card; @@ -658,6 +1022,14 @@ static void mmc_sd_remove(struct mmc_host *host)  }  /* + * Card detection - card is alive. + */ +static int mmc_sd_alive(struct mmc_host *host) +{ +	return mmc_send_status(host->card, NULL); +} + +/*   * Card detection callback from host.   */  static void mmc_sd_detect(struct mmc_host *host) @@ -667,68 +1039,150 @@ static void mmc_sd_detect(struct mmc_host *host)  	BUG_ON(!host);  	BUG_ON(!host->card); -	mmc_claim_host(host); +	mmc_get_card(host->card);  	/*  	 * Just check if our card has been removed.  	 */ -	err = mmc_send_status(host->card, NULL); +	err = _mmc_detect_card_removed(host); -	mmc_release_host(host); +	mmc_put_card(host->card);  	if (err) {  		mmc_sd_remove(host);  		mmc_claim_host(host);  		mmc_detach_bus(host); +		mmc_power_off(host);  		mmc_release_host(host);  	}  } -/* - * Suspend callback from host. - */ -static int mmc_sd_suspend(struct mmc_host *host) +static int _mmc_sd_suspend(struct mmc_host *host)  { +	int err = 0; +  	BUG_ON(!host);  	BUG_ON(!host->card);  	mmc_claim_host(host); + +	if (mmc_card_suspended(host->card)) +		goto out; +  	if (!mmc_host_is_spi(host)) -		mmc_deselect_cards(host); -	host->card->state &= ~MMC_STATE_HIGHSPEED; +		err = mmc_deselect_cards(host); + +	if (!err) { +		mmc_power_off(host); +		mmc_card_set_suspended(host->card); +	} + +out:  	mmc_release_host(host); +	return err; +} -	return 0; +/* + * Callback for suspend + */ +static int mmc_sd_suspend(struct mmc_host *host) +{ +	int err; + +	err = _mmc_sd_suspend(host); +	if (!err) { +		pm_runtime_disable(&host->card->dev); +		pm_runtime_set_suspended(&host->card->dev); +	} + +	return err;  }  /* - * Resume callback from host. - *   * This function tries to determine if the same card is still present   * and, if so, restore all state to it.   */ -static int mmc_sd_resume(struct mmc_host *host) +static int _mmc_sd_resume(struct mmc_host *host)  { -	int err; +	int err = 0;  	BUG_ON(!host);  	BUG_ON(!host->card);  	mmc_claim_host(host); -	err = mmc_sd_init_card(host, host->ocr, host->card); + +	if (!mmc_card_suspended(host->card)) +		goto out; + +	mmc_power_up(host, host->card->ocr); +	err = mmc_sd_init_card(host, host->card->ocr, host->card); +	mmc_card_clr_suspended(host->card); + +out:  	mmc_release_host(host); +	return err; +} + +/* + * Callback for resume + */ +static int mmc_sd_resume(struct mmc_host *host) +{ +	int err = 0; + +	if (!(host->caps & MMC_CAP_RUNTIME_RESUME)) { +		err = _mmc_sd_resume(host); +		pm_runtime_set_active(&host->card->dev); +		pm_runtime_mark_last_busy(&host->card->dev); +	} +	pm_runtime_enable(&host->card->dev); + +	return err; +} + +/* + * Callback for runtime_suspend. + */ +static int mmc_sd_runtime_suspend(struct mmc_host *host) +{ +	int err; + +	if (!(host->caps & MMC_CAP_AGGRESSIVE_PM)) +		return 0; + +	err = _mmc_sd_suspend(host); +	if (err) +		pr_err("%s: error %d doing aggessive suspend\n", +			mmc_hostname(host), err);  	return err;  } +/* + * Callback for runtime_resume. + */ +static int mmc_sd_runtime_resume(struct mmc_host *host) +{ +	int err; + +	if (!(host->caps & (MMC_CAP_AGGRESSIVE_PM | MMC_CAP_RUNTIME_RESUME))) +		return 0; + +	err = _mmc_sd_resume(host); +	if (err) +		pr_err("%s: error %d doing aggessive resume\n", +			mmc_hostname(host), err); + +	return 0; +} +  static int mmc_sd_power_restore(struct mmc_host *host)  {  	int ret; -	host->card->state &= ~MMC_STATE_HIGHSPEED;  	mmc_claim_host(host); -	ret = mmc_sd_init_card(host, host->ocr, host->card); +	ret = mmc_sd_init_card(host, host->card->ocr, host->card);  	mmc_release_host(host);  	return ret; @@ -737,41 +1191,33 @@ static int mmc_sd_power_restore(struct mmc_host *host)  static const struct mmc_bus_ops mmc_sd_ops = {  	.remove = mmc_sd_remove,  	.detect = mmc_sd_detect, -	.suspend = NULL, -	.resume = NULL, -	.power_restore = mmc_sd_power_restore, -}; - -static const struct mmc_bus_ops mmc_sd_ops_unsafe = { -	.remove = mmc_sd_remove, -	.detect = mmc_sd_detect, +	.runtime_suspend = mmc_sd_runtime_suspend, +	.runtime_resume = mmc_sd_runtime_resume,  	.suspend = mmc_sd_suspend,  	.resume = mmc_sd_resume,  	.power_restore = mmc_sd_power_restore, +	.alive = mmc_sd_alive, +	.shutdown = mmc_sd_suspend,  }; -static void mmc_sd_attach_bus_ops(struct mmc_host *host) -{ -	const struct mmc_bus_ops *bus_ops; - -	if (!mmc_card_is_removable(host)) -		bus_ops = &mmc_sd_ops_unsafe; -	else -		bus_ops = &mmc_sd_ops; -	mmc_attach_bus(host, bus_ops); -} -  /*   * Starting point for SD card init.   */ -int mmc_attach_sd(struct mmc_host *host, u32 ocr) +int mmc_attach_sd(struct mmc_host *host)  {  	int err; +	u32 ocr, rocr;  	BUG_ON(!host);  	WARN_ON(!host->claimed); -	mmc_sd_attach_bus_ops(host); +	err = mmc_send_app_op_cond(host, 0, &ocr); +	if (err) +		return err; + +	mmc_attach_bus(host, &mmc_sd_ops); +	if (host->ocr_avail_sd) +		host->ocr_avail = host->ocr_avail_sd;  	/*  	 * We need to get OCR a different way for SPI. @@ -784,30 +1230,12 @@ int mmc_attach_sd(struct mmc_host *host, u32 ocr)  			goto err;  	} -	/* -	 * Sanity check the voltages that the card claims to -	 * support. -	 */ -	if (ocr & 0x7F) { -		printk(KERN_WARNING "%s: card claims to support voltages " -		       "below the defined range. These will be ignored.\n", -		       mmc_hostname(host)); -		ocr &= ~0x7F; -	} - -	if (ocr & MMC_VDD_165_195) { -		printk(KERN_WARNING "%s: SD card claims to support the " -		       "incompletely defined 'low voltage range'. This " -		       "will be ignored.\n", mmc_hostname(host)); -		ocr &= ~MMC_VDD_165_195; -	} - -	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;  	} @@ -815,27 +1243,27 @@ int mmc_attach_sd(struct mmc_host *host, u32 ocr)  	/*  	 * Detect and init the card.  	 */ -	err = mmc_sd_init_card(host, host->ocr, NULL); +	err = mmc_sd_init_card(host, rocr, NULL);  	if (err)  		goto err;  	mmc_release_host(host); -  	err = mmc_add_card(host->card); +	mmc_claim_host(host);  	if (err)  		goto remove_card;  	return 0;  remove_card: +	mmc_release_host(host);  	mmc_remove_card(host->card);  	host->card = NULL;  	mmc_claim_host(host);  err:  	mmc_detach_bus(host); -	mmc_release_host(host); -	printk(KERN_ERR "%s: error %d whilst initialising SD card\n", +	pr_err("%s: error %d whilst initialising SD card\n",  		mmc_hostname(host), err);  	return err; diff --git a/drivers/mmc/core/sd.h b/drivers/mmc/core/sd.h index 3d8800fa760..aab824a9a7f 100644 --- a/drivers/mmc/core/sd.h +++ b/drivers/mmc/core/sd.h @@ -5,13 +5,12 @@  extern struct device_type sd_type; -int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid); +int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid, u32 *rocr);  int mmc_sd_get_csd(struct mmc_host *host, struct mmc_card *card);  void mmc_decode_cid(struct mmc_card *card);  int mmc_sd_setup_card(struct mmc_host *host, struct mmc_card *card,  	bool reinit);  unsigned mmc_sd_get_max_clock(struct mmc_card *card);  int mmc_sd_switch_hs(struct mmc_card *card); -void mmc_sd_go_highspeed(struct mmc_card *card);  #endif diff --git a/drivers/mmc/core/sd_ops.c b/drivers/mmc/core/sd_ops.c index 797cdb5887f..274ef00b446 100644 --- a/drivers/mmc/core/sd_ops.c +++ b/drivers/mmc/core/sd_ops.c @@ -9,7 +9,9 @@   * your option) any later version.   */ +#include <linux/slab.h>  #include <linux/types.h> +#include <linux/export.h>  #include <linux/scatterlist.h>  #include <linux/mmc/host.h> @@ -20,10 +22,10 @@  #include "core.h"  #include "sd_ops.h" -static int mmc_app_cmd(struct mmc_host *host, struct mmc_card *card) +int mmc_app_cmd(struct mmc_host *host, struct mmc_card *card)  {  	int err; -	struct mmc_command cmd; +	struct mmc_command cmd = {0};  	BUG_ON(!host);  	BUG_ON(card && (card->host != host)); @@ -48,6 +50,7 @@ static int mmc_app_cmd(struct mmc_host *host, struct mmc_card *card)  	return 0;  } +EXPORT_SYMBOL_GPL(mmc_app_cmd);  /**   *	mmc_wait_for_app_cmd - start an application command and wait for @@ -65,7 +68,7 @@ static int mmc_app_cmd(struct mmc_host *host, struct mmc_card *card)  int mmc_wait_for_app_cmd(struct mmc_host *host, struct mmc_card *card,  	struct mmc_command *cmd, int retries)  { -	struct mmc_request mrq; +	struct mmc_request mrq = {NULL};  	int i, err; @@ -118,13 +121,11 @@ EXPORT_SYMBOL(mmc_wait_for_app_cmd);  int mmc_app_set_bus_width(struct mmc_card *card, int width)  {  	int err; -	struct mmc_command cmd; +	struct mmc_command cmd = {0};  	BUG_ON(!card);  	BUG_ON(!card->host); -	memset(&cmd, 0, sizeof(struct mmc_command)); -  	cmd.opcode = SD_APP_SET_BUS_WIDTH;  	cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; @@ -148,13 +149,11 @@ int mmc_app_set_bus_width(struct mmc_card *card, int width)  int mmc_send_app_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr)  { -	struct mmc_command cmd; +	struct mmc_command cmd = {0};  	int i, err = 0;  	BUG_ON(!host); -	memset(&cmd, 0, sizeof(struct mmc_command)); -  	cmd.opcode = SD_APP_OP_COND;  	if (mmc_host_is_spi(host))  		cmd.arg = ocr & (1 << 30); /* SPI only defines one bit */ @@ -193,7 +192,7 @@ int mmc_send_app_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr)  int mmc_send_if_cond(struct mmc_host *host, u32 ocr)  { -	struct mmc_command cmd; +	struct mmc_command cmd = {0};  	int err;  	static const u8 test_pattern = 0xAA;  	u8 result_pattern; @@ -225,13 +224,11 @@ int mmc_send_if_cond(struct mmc_host *host, u32 ocr)  int mmc_send_relative_addr(struct mmc_host *host, unsigned int *rca)  {  	int err; -	struct mmc_command cmd; +	struct mmc_command cmd = {0};  	BUG_ON(!host);  	BUG_ON(!rca); -	memset(&cmd, 0, sizeof(struct mmc_command)); -  	cmd.opcode = SD_SEND_RELATIVE_ADDR;  	cmd.arg = 0;  	cmd.flags = MMC_RSP_R6 | MMC_CMD_BCR; @@ -248,10 +245,11 @@ int mmc_send_relative_addr(struct mmc_host *host, unsigned int *rca)  int mmc_app_send_scr(struct mmc_card *card, u32 *scr)  {  	int err; -	struct mmc_request mrq; -	struct mmc_command cmd; -	struct mmc_data data; +	struct mmc_request mrq = {NULL}; +	struct mmc_command cmd = {0}; +	struct mmc_data data = {0};  	struct scatterlist sg; +	void *data_buf;  	BUG_ON(!card);  	BUG_ON(!card->host); @@ -263,9 +261,12 @@ int mmc_app_send_scr(struct mmc_card *card, u32 *scr)  	if (err)  		return err; -	memset(&mrq, 0, sizeof(struct mmc_request)); -	memset(&cmd, 0, sizeof(struct mmc_command)); -	memset(&data, 0, sizeof(struct mmc_data)); +	/* dma onto stack is unsafe/nonportable, but callers to this +	 * routine normally provide temporary on-stack buffers ... +	 */ +	data_buf = kmalloc(sizeof(card->raw_scr), GFP_KERNEL); +	if (data_buf == NULL) +		return -ENOMEM;  	mrq.cmd = &cmd;  	mrq.data = &data; @@ -280,12 +281,15 @@ int mmc_app_send_scr(struct mmc_card *card, u32 *scr)  	data.sg = &sg;  	data.sg_len = 1; -	sg_init_one(&sg, scr, 8); +	sg_init_one(&sg, data_buf, 8);  	mmc_set_data_timeout(&data, card);  	mmc_wait_for_req(card->host, &mrq); +	memcpy(scr, data_buf, sizeof(card->raw_scr)); +	kfree(data_buf); +  	if (cmd.error)  		return cmd.error;  	if (data.error) @@ -300,9 +304,9 @@ int mmc_app_send_scr(struct mmc_card *card, u32 *scr)  int mmc_sd_switch(struct mmc_card *card, int mode, int group,  	u8 value, u8 *resp)  { -	struct mmc_request mrq; -	struct mmc_command cmd; -	struct mmc_data data; +	struct mmc_request mrq = {NULL}; +	struct mmc_command cmd = {0}; +	struct mmc_data data = {0};  	struct scatterlist sg;  	BUG_ON(!card); @@ -313,10 +317,6 @@ int mmc_sd_switch(struct mmc_card *card, int mode, int group,  	mode = !!mode;  	value &= 0xF; -	memset(&mrq, 0, sizeof(struct mmc_request)); -	memset(&cmd, 0, sizeof(struct mmc_command)); -	memset(&data, 0, sizeof(struct mmc_data)); -  	mrq.cmd = &cmd;  	mrq.data = &data; @@ -349,9 +349,9 @@ int mmc_sd_switch(struct mmc_card *card, int mode, int group,  int mmc_app_sd_status(struct mmc_card *card, void *ssr)  {  	int err; -	struct mmc_request mrq; -	struct mmc_command cmd; -	struct mmc_data data; +	struct mmc_request mrq = {NULL}; +	struct mmc_command cmd = {0}; +	struct mmc_data data = {0};  	struct scatterlist sg;  	BUG_ON(!card); @@ -364,10 +364,6 @@ int mmc_app_sd_status(struct mmc_card *card, void *ssr)  	if (err)  		return err; -	memset(&mrq, 0, sizeof(struct mmc_request)); -	memset(&cmd, 0, sizeof(struct mmc_command)); -	memset(&data, 0, sizeof(struct mmc_data)); -  	mrq.cmd = &cmd;  	mrq.data = &data; diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index c3ad1058cd3..e636d9e99e4 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c @@ -14,8 +14,10 @@  #include <linux/mmc/host.h>  #include <linux/mmc/card.h> +#include <linux/mmc/mmc.h>  #include <linux/mmc/sdio.h>  #include <linux/mmc/sdio_func.h> +#include <linux/mmc/sdio_ids.h>  #include "core.h"  #include "bus.h" @@ -31,6 +33,11 @@ static int sdio_read_fbr(struct sdio_func *func)  	int ret;  	unsigned char data; +	if (mmc_card_nonstd_func_interface(func->card)) { +		func->class = SDIO_CLASS_NONE; +		return 0; +	} +  	ret = mmc_io_rw_direct(func->card, 0, 0,  		SDIO_FBR_BASE(func->num) + SDIO_FBR_STD_IF, 0, &data);  	if (ret) @@ -91,11 +98,13 @@ fail:  	return ret;  } -static int sdio_read_cccr(struct mmc_card *card) +static int sdio_read_cccr(struct mmc_card *card, u32 ocr)  {  	int ret;  	int cccr_vsn; +	int uhs = ocr & R4_18V_PRESENT;  	unsigned char data; +	unsigned char speed;  	memset(&card->cccr, 0, sizeof(struct sdio_cccr)); @@ -105,8 +114,8 @@ static int sdio_read_cccr(struct mmc_card *card)  	cccr_vsn = data & 0x0f; -	if (cccr_vsn > SDIO_CCCR_REV_1_20) { -		printk(KERN_ERR "%s: unrecognised CCCR structure version %d\n", +	if (cccr_vsn > SDIO_CCCR_REV_3_00) { +		pr_err("%s: unrecognised CCCR structure version %d\n",  			mmc_hostname(card->host), cccr_vsn);  		return -EINVAL;  	} @@ -134,12 +143,57 @@ static int sdio_read_cccr(struct mmc_card *card)  	}  	if (cccr_vsn >= SDIO_CCCR_REV_1_20) { -		ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_SPEED, 0, &data); +		ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_SPEED, 0, &speed);  		if (ret)  			goto out; -		if (data & SDIO_SPEED_SHS) -			card->cccr.high_speed = 1; +		card->scr.sda_spec3 = 0; +		card->sw_caps.sd3_bus_mode = 0; +		card->sw_caps.sd3_drv_type = 0; +		if (cccr_vsn >= SDIO_CCCR_REV_3_00 && uhs) { +			card->scr.sda_spec3 = 1; +			ret = mmc_io_rw_direct(card, 0, 0, +				SDIO_CCCR_UHS, 0, &data); +			if (ret) +				goto out; + +			if (mmc_host_uhs(card->host)) { +				if (data & SDIO_UHS_DDR50) +					card->sw_caps.sd3_bus_mode +						|= SD_MODE_UHS_DDR50; + +				if (data & SDIO_UHS_SDR50) +					card->sw_caps.sd3_bus_mode +						|= SD_MODE_UHS_SDR50; + +				if (data & SDIO_UHS_SDR104) +					card->sw_caps.sd3_bus_mode +						|= SD_MODE_UHS_SDR104; +			} + +			ret = mmc_io_rw_direct(card, 0, 0, +				SDIO_CCCR_DRIVE_STRENGTH, 0, &data); +			if (ret) +				goto out; + +			if (data & SDIO_DRIVE_SDTA) +				card->sw_caps.sd3_drv_type |= SD_DRIVER_TYPE_A; +			if (data & SDIO_DRIVE_SDTC) +				card->sw_caps.sd3_drv_type |= SD_DRIVER_TYPE_C; +			if (data & SDIO_DRIVE_SDTD) +				card->sw_caps.sd3_drv_type |= SD_DRIVER_TYPE_D; +		} + +		/* if no uhs mode ensure we check for high speed */ +		if (!card->sw_caps.sd3_bus_mode) { +			if (speed & SDIO_SPEED_SHS) { +				card->cccr.high_speed = 1; +				card->sw_caps.hs_max_dtr = 50000000; +			} else { +				card->cccr.high_speed = 0; +				card->sw_caps.hs_max_dtr = 25000000; +			} +		}  	}  out: @@ -161,6 +215,12 @@ static int sdio_enable_wide(struct mmc_card *card)  	if (ret)  		return ret; +	if ((ctrl & SDIO_BUS_WIDTH_MASK) == SDIO_BUS_WIDTH_RESERVED) +		pr_warning("%s: SDIO_CCCR_IF is invalid: 0x%02x\n", +			   mmc_hostname(card->host), ctrl); + +	/* set as 4-bit bus width */ +	ctrl &= ~SDIO_BUS_WIDTH_MASK;  	ctrl |= SDIO_BUS_WIDTH_4BIT;  	ret = mmc_io_rw_direct(card, 1, 0, SDIO_CCCR_IF, ctrl, NULL); @@ -181,7 +241,7 @@ static int sdio_disable_cd(struct mmc_card *card)  	int ret;  	u8 ctrl; -	if (!card->cccr.disable_cd) +	if (!mmc_card_disable_cd(card))  		return 0;  	ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_IF, 0, &ctrl); @@ -303,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 @@ -321,6 +381,206 @@ static unsigned mmc_sdio_get_max_clock(struct mmc_card *card)  	return max_dtr;  } +static unsigned char host_drive_to_sdio_drive(int host_strength) +{ +	switch (host_strength) { +	case MMC_SET_DRIVER_TYPE_A: +		return SDIO_DTSx_SET_TYPE_A; +	case MMC_SET_DRIVER_TYPE_B: +		return SDIO_DTSx_SET_TYPE_B; +	case MMC_SET_DRIVER_TYPE_C: +		return SDIO_DTSx_SET_TYPE_C; +	case MMC_SET_DRIVER_TYPE_D: +		return SDIO_DTSx_SET_TYPE_D; +	default: +		return SDIO_DTSx_SET_TYPE_B; +	} +} + +static void sdio_select_driver_type(struct mmc_card *card) +{ +	int host_drv_type = SD_DRIVER_TYPE_B; +	int card_drv_type = SD_DRIVER_TYPE_B; +	int drive_strength; +	unsigned char card_strength; +	int err; + +	/* +	 * If the host doesn't support any of the Driver Types A,C or D, +	 * or there is no board specific handler then default Driver +	 * Type B is used. +	 */ +	if (!(card->host->caps & +		(MMC_CAP_DRIVER_TYPE_A | +		 MMC_CAP_DRIVER_TYPE_C | +		 MMC_CAP_DRIVER_TYPE_D))) +		return; + +	if (!card->host->ops->select_drive_strength) +		return; + +	if (card->host->caps & MMC_CAP_DRIVER_TYPE_A) +		host_drv_type |= SD_DRIVER_TYPE_A; + +	if (card->host->caps & MMC_CAP_DRIVER_TYPE_C) +		host_drv_type |= SD_DRIVER_TYPE_C; + +	if (card->host->caps & MMC_CAP_DRIVER_TYPE_D) +		host_drv_type |= SD_DRIVER_TYPE_D; + +	if (card->sw_caps.sd3_drv_type & SD_DRIVER_TYPE_A) +		card_drv_type |= SD_DRIVER_TYPE_A; + +	if (card->sw_caps.sd3_drv_type & SD_DRIVER_TYPE_C) +		card_drv_type |= SD_DRIVER_TYPE_C; + +	if (card->sw_caps.sd3_drv_type & SD_DRIVER_TYPE_D) +		card_drv_type |= SD_DRIVER_TYPE_D; + +	/* +	 * The drive strength that the hardware can support +	 * depends on the board design.  Pass the appropriate +	 * information and let the hardware specific code +	 * return what is possible given the options +	 */ +	drive_strength = card->host->ops->select_drive_strength( +		card->sw_caps.uhs_max_dtr, +		host_drv_type, card_drv_type); + +	/* if error just use default for drive strength B */ +	err = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_DRIVE_STRENGTH, 0, +		&card_strength); +	if (err) +		return; + +	card_strength &= ~(SDIO_DRIVE_DTSx_MASK<<SDIO_DRIVE_DTSx_SHIFT); +	card_strength |= host_drive_to_sdio_drive(drive_strength); + +	err = mmc_io_rw_direct(card, 1, 0, SDIO_CCCR_DRIVE_STRENGTH, +		card_strength, NULL); + +	/* if error default to drive strength B */ +	if (!err) +		mmc_set_driver_type(card->host, drive_strength); +} + + +static int sdio_set_bus_speed_mode(struct mmc_card *card) +{ +	unsigned int bus_speed, timing; +	int err; +	unsigned char speed; + +	/* +	 * If the host doesn't support any of the UHS-I modes, fallback on +	 * default speed. +	 */ +	if (!mmc_host_uhs(card->host)) +		return 0; + +	bus_speed = SDIO_SPEED_SDR12; +	timing = MMC_TIMING_UHS_SDR12; +	if ((card->host->caps & MMC_CAP_UHS_SDR104) && +	    (card->sw_caps.sd3_bus_mode & SD_MODE_UHS_SDR104)) { +			bus_speed = SDIO_SPEED_SDR104; +			timing = MMC_TIMING_UHS_SDR104; +			card->sw_caps.uhs_max_dtr = UHS_SDR104_MAX_DTR; +			card->sd_bus_speed = UHS_SDR104_BUS_SPEED; +	} else if ((card->host->caps & MMC_CAP_UHS_DDR50) && +		   (card->sw_caps.sd3_bus_mode & SD_MODE_UHS_DDR50)) { +			bus_speed = SDIO_SPEED_DDR50; +			timing = MMC_TIMING_UHS_DDR50; +			card->sw_caps.uhs_max_dtr = UHS_DDR50_MAX_DTR; +			card->sd_bus_speed = UHS_DDR50_BUS_SPEED; +	} else if ((card->host->caps & (MMC_CAP_UHS_SDR104 | +		    MMC_CAP_UHS_SDR50)) && (card->sw_caps.sd3_bus_mode & +		    SD_MODE_UHS_SDR50)) { +			bus_speed = SDIO_SPEED_SDR50; +			timing = MMC_TIMING_UHS_SDR50; +			card->sw_caps.uhs_max_dtr = UHS_SDR50_MAX_DTR; +			card->sd_bus_speed = UHS_SDR50_BUS_SPEED; +	} else if ((card->host->caps & (MMC_CAP_UHS_SDR104 | +		    MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR25)) && +		   (card->sw_caps.sd3_bus_mode & SD_MODE_UHS_SDR25)) { +			bus_speed = SDIO_SPEED_SDR25; +			timing = MMC_TIMING_UHS_SDR25; +			card->sw_caps.uhs_max_dtr = UHS_SDR25_MAX_DTR; +			card->sd_bus_speed = UHS_SDR25_BUS_SPEED; +	} else if ((card->host->caps & (MMC_CAP_UHS_SDR104 | +		    MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR25 | +		    MMC_CAP_UHS_SDR12)) && (card->sw_caps.sd3_bus_mode & +		    SD_MODE_UHS_SDR12)) { +			bus_speed = SDIO_SPEED_SDR12; +			timing = MMC_TIMING_UHS_SDR12; +			card->sw_caps.uhs_max_dtr = UHS_SDR12_MAX_DTR; +			card->sd_bus_speed = UHS_SDR12_BUS_SPEED; +	} + +	err = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_SPEED, 0, &speed); +	if (err) +		return err; + +	speed &= ~SDIO_SPEED_BSS_MASK; +	speed |= bus_speed; +	err = mmc_io_rw_direct(card, 1, 0, SDIO_CCCR_SPEED, speed, NULL); +	if (err) +		return err; + +	if (bus_speed) { +		mmc_set_timing(card->host, timing); +		mmc_set_clock(card->host, card->sw_caps.uhs_max_dtr); +	} + +	return 0; +} + +/* + * UHS-I specific initialization procedure + */ +static int mmc_sdio_init_uhs_card(struct mmc_card *card) +{ +	int err; + +	if (!card->scr.sda_spec3) +		return 0; + +	/* +	 * Switch to wider bus (if supported). +	 */ +	if (card->host->caps & MMC_CAP_4_BIT_DATA) { +		err = sdio_enable_4bit_bus(card); +		if (err > 0) { +			mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4); +			err = 0; +		} +	} + +	/* Set the driver strength for the card */ +	sdio_select_driver_type(card); + +	/* Set bus speed mode of the card */ +	err = sdio_set_bus_speed_mode(card); +	if (err) +		goto out; + +	/* +	 * SPI mode doesn't define CMD19 and tuning is only valid for SDR50 and +	 * SDR104 mode SD-cards. Note that tuning is mandatory for SDR104. +	 */ +	if (!mmc_host_is_spi(card->host) && card->host->ops->execute_tuning && +			((card->sw_caps.sd3_bus_mode & SD_MODE_UHS_SDR50) || +			 (card->sw_caps.sd3_bus_mode & SD_MODE_UHS_SDR104))) { +		mmc_host_clk_hold(card->host); +		err = card->host->ops->execute_tuning(card->host, +						      MMC_SEND_TUNING_BLOCK); +		mmc_host_clk_release(card->host); +	} + +out: + +	return err; +} +  /*   * Handle the detection and initialisation of a card.   * @@ -332,15 +592,29 @@ 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; +	} +  	/*  	 * 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;  	} @@ -363,8 +637,8 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,  		goto err;  	} -	if (ocr & R4_MEMORY_PRESENT -	    && mmc_sd_get_cid(host, host->ocr & ocr, card->raw_cid) == 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 || @@ -388,6 +662,31 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,  		host->ops->init_card(host, card);  	/* +	 * If the host and card support UHS-I mode request the card +	 * to switch to 1.8V signaling level.  No 1.8v signalling if +	 * UHS mode is not enabled to maintain compatibility and some +	 * systems that claim 1.8v signalling in fact do not support +	 * it. +	 */ +	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); +			mmc_send_if_cond(host, host->ocr_avail); +			mmc_remove_card(card); +			retries--; +			goto try_again; +		} else if (err) { +			ocr &= ~R4_18V_PRESENT; +		} +		err = 0; +	} else { +		ocr &= ~R4_18V_PRESENT; +	} + +	/*  	 * For native busses:  set card RCA and quit open drain mode.  	 */  	if (!powered_resume && !mmc_host_is_spi(host)) { @@ -395,7 +694,13 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,  		if (err)  			goto remove; -		mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL); +		/* +		 * Update oldcard with the new RCA received from the SDIO +		 * device -- we're doing this so that it's updated in the +		 * "card" struct when oldcard overwrites that later. +		 */ +		if (oldcard) +			oldcard->rca = card->rca;  	}  	/* @@ -428,7 +733,6 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,  		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);  		} @@ -438,7 +742,7 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,  	/*  	 * Read the common registers.  	 */ -	err = sdio_read_cccr(card); +	err = sdio_read_cccr(card, ocr);  	if (err)  		goto remove; @@ -458,6 +762,8 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,  		card = oldcard;  	} +	card->ocr = ocr_card; +	mmc_fixup_device(card, NULL);  	if (card->type == MMC_TYPE_SD_COMBO) {  		err = mmc_sd_setup_card(host, card, oldcard != NULL); @@ -479,29 +785,36 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,  	if (err)  		goto remove; -	/* -	 * Switch to high-speed (if supported). -	 */ -	err = sdio_enable_hs(card); -	if (err > 0) -		mmc_sd_go_highspeed(card); -	else if (err) -		goto remove; - -	/* -	 * Change to the card's maximum speed. -	 */ -	mmc_set_clock(host, mmc_sdio_get_max_clock(card)); +	/* Initialization sequence for UHS-I cards */ +	/* Only if card supports 1.8v and UHS signaling */ +	if ((ocr & R4_18V_PRESENT) && card->sw_caps.sd3_bus_mode) { +		err = mmc_sdio_init_uhs_card(card); +		if (err) +			goto remove; +	} else { +		/* +		 * Switch to high-speed (if supported). +		 */ +		err = sdio_enable_hs(card); +		if (err > 0) +			mmc_set_timing(card->host, MMC_TIMING_SD_HS); +		else if (err) +			goto remove; -	/* -	 * Switch to wider bus (if supported). -	 */ -	err = sdio_enable_4bit_bus(card); -	if (err > 0) -		mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4); -	else if (err) -		goto remove; +		/* +		 * Change to the card's maximum speed. +		 */ +		mmc_set_clock(host, mmc_sdio_get_max_clock(card)); +		/* +		 * Switch to wider bus (if supported). +		 */ +		err = sdio_enable_4bit_bus(card); +		if (err > 0) +			mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4); +		else if (err) +			goto remove; +	}  finish:  	if (!oldcard)  		host->card = card; @@ -537,6 +850,14 @@ static void mmc_sdio_remove(struct mmc_host *host)  }  /* + * Card detection - card is alive. + */ +static int mmc_sdio_alive(struct mmc_host *host) +{ +	return mmc_select_card(host->card); +} + +/*   * Card detection callback from host.   */  static void mmc_sdio_detect(struct mmc_host *host) @@ -547,38 +868,54 @@ static void mmc_sdio_detect(struct mmc_host *host)  	BUG_ON(!host->card);  	/* Make sure card is powered before detecting it */ -	err = pm_runtime_get_sync(&host->card->dev); -	if (err < 0) -		goto out; +	if (host->caps & MMC_CAP_POWER_OFF_CARD) { +		err = pm_runtime_get_sync(&host->card->dev); +		if (err < 0) { +			pm_runtime_put_noidle(&host->card->dev); +			goto out; +		} +	}  	mmc_claim_host(host);  	/*  	 * Just check if our card has been removed.  	 */ -	err = mmc_select_card(host->card); +	err = _mmc_detect_card_removed(host);  	mmc_release_host(host); +	/* +	 * Tell PM core it's OK to power off the card now. +	 * +	 * The _sync variant is used in order to ensure that the card +	 * is left powered off in case an error occurred, and the card +	 * is going to be removed. +	 * +	 * Since there is no specific reason to believe a new user +	 * is about to show up at this point, the _sync variant is +	 * desirable anyway. +	 */ +	if (host->caps & MMC_CAP_POWER_OFF_CARD) +		pm_runtime_put_sync(&host->card->dev); +  out:  	if (err) {  		mmc_sdio_remove(host);  		mmc_claim_host(host);  		mmc_detach_bus(host); +		mmc_power_off(host);  		mmc_release_host(host);  	} - -	/* Tell PM core that we're done */ -	pm_runtime_put(&host->card->dev);  }  /* - * SDIO suspend.  We need to suspend all functions separately. + * SDIO pre_suspend.  We need to suspend all functions separately.   * Therefore all registered functions must have drivers with suspend   * and resume methods.  Failing that we simply remove the whole card.   */ -static int mmc_sdio_suspend(struct mmc_host *host) +static int mmc_sdio_pre_suspend(struct mmc_host *host)  {  	int i, err = 0; @@ -589,62 +926,77 @@ static int mmc_sdio_suspend(struct mmc_host *host)  			if (!pmops || !pmops->suspend || !pmops->resume) {  				/* force removal of entire card in that case */  				err = -ENOSYS; -			} else -				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 && host->pm_flags & MMC_PM_KEEP_POWER) { +	return err; +} + +/* + * SDIO suspend.  Suspend all functions separately. + */ +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);  		sdio_disable_wide(host->card);  		mmc_release_host(host);  	} -	return err; +	if (!mmc_card_keep_power(host)) +		mmc_power_off(host); + +	return 0;  }  static int mmc_sdio_resume(struct mmc_host *host)  { -	int i, err; +	int err = 0;  	BUG_ON(!host);  	BUG_ON(!host->card);  	/* Basic card reinitialization. */  	mmc_claim_host(host); -	err = mmc_sdio_init_card(host, host->ocr, host->card, -				 (host->pm_flags & MMC_PM_KEEP_POWER)); -	if (!err && host->sdio_irqs) -		mmc_signal_sdio_irq(host); -	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); +	/* Restore power if needed */ +	if (!mmc_card_keep_power(host)) { +		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. +		 * Note that currently runtime PM is only enabled +		 * for SDIO cards that are MMC_CAP_POWER_OFF_CARD +		 */ +		if (host->caps & MMC_CAP_POWER_OFF_CARD) { +			pm_runtime_disable(&host->card->dev); +			pm_runtime_set_active(&host->card->dev); +			pm_runtime_enable(&host->card->dev);  		}  	} +	/* No need to reinitialize powered-resumed nonremovable cards */ +	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->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 */ +		err = sdio_enable_4bit_bus(host->card); +		if (err > 0) { +			mmc_set_bus_width(host, MMC_BUS_WIDTH_4); +			err = 0; +		} +	} + +	if (!err && host->sdio_irqs) +		wake_up_process(host->sdio_irq_thread); +	mmc_release_host(host); + +	host->pm_flags &= ~MMC_PM_KEEP_POWER;  	return err;  } @@ -656,55 +1008,97 @@ static int mmc_sdio_power_restore(struct mmc_host *host)  	BUG_ON(!host->card);  	mmc_claim_host(host); -	ret = mmc_sdio_init_card(host, host->ocr, host->card, -			(host->pm_flags & MMC_PM_KEEP_POWER)); + +	/* +	 * Reset the card by performing the same steps that are taken by +	 * mmc_rescan_try_freq() and mmc_attach_sdio() during a "normal" probe. +	 * +	 * sdio_reset() is technically not needed. Having just powered up the +	 * hardware, it should already be in reset state. However, some +	 * platforms (such as SD8686 on OLPC) do not instantly cut power, +	 * meaning that a reset is required when restoring power soon after +	 * powering off. It is harmless in other cases. +	 * +	 * The CMD5 reset (mmc_send_io_op_cond()), according to the SDIO spec, +	 * is not necessary for non-removable cards. However, it is required +	 * for OLPC SD8686 (which expects a [CMD5,5,3,7] init sequence), and +	 * harmless in other situations. +	 * +	 */ + +	sdio_reset(host); +	mmc_go_idle(host); +	mmc_send_if_cond(host, host->ocr_avail); + +	ret = mmc_send_io_op_cond(host, 0, NULL); +	if (ret) +		goto out; + +	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); + +out:  	mmc_release_host(host);  	return ret;  } +static int mmc_sdio_runtime_suspend(struct mmc_host *host) +{ +	/* No references to the card, cut the power to it. */ +	mmc_power_off(host); +	return 0; +} + +static int mmc_sdio_runtime_resume(struct mmc_host *host) +{ +	/* Restore power and re-initialize. */ +	mmc_power_up(host, host->card->ocr); +	return mmc_sdio_power_restore(host); +} +  static const struct mmc_bus_ops mmc_sdio_ops = {  	.remove = mmc_sdio_remove,  	.detect = mmc_sdio_detect, +	.pre_suspend = mmc_sdio_pre_suspend,  	.suspend = mmc_sdio_suspend,  	.resume = mmc_sdio_resume, +	.runtime_suspend = mmc_sdio_runtime_suspend, +	.runtime_resume = mmc_sdio_runtime_resume,  	.power_restore = mmc_sdio_power_restore, +	.alive = mmc_sdio_alive,  };  /*   * Starting point for SDIO card init.   */ -int mmc_attach_sdio(struct mmc_host *host, u32 ocr) +int mmc_attach_sdio(struct mmc_host *host)  { -	int err; -	int i, funcs; +	int err, i, funcs; +	u32 ocr, rocr;  	struct mmc_card *card;  	BUG_ON(!host);  	WARN_ON(!host->claimed); +	err = mmc_send_io_op_cond(host, 0, &ocr); +	if (err) +		return err; +  	mmc_attach_bus(host, &mmc_sdio_ops); +	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) { -		printk(KERN_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;  	} @@ -712,22 +1106,28 @@ int mmc_attach_sdio(struct mmc_host *host, u32 ocr)  	/*  	 * Detect and init the card.  	 */ -	err = mmc_sdio_init_card(host, host->ocr, NULL, 0); +	err = mmc_sdio_init_card(host, rocr, NULL, 0);  	if (err)  		goto err; +  	card = host->card;  	/* -	 * Let runtime PM core know our card is active +	 * Enable runtime PM only if supported by host+card+board  	 */ -	err = pm_runtime_set_active(&card->dev); -	if (err) -		goto remove; +	if (host->caps & MMC_CAP_POWER_OFF_CARD) { +		/* +		 * Let runtime PM core know our card is active +		 */ +		err = pm_runtime_set_active(&card->dev); +		if (err) +			goto remove; -	/* -	 * Enable runtime PM for this card -	 */ -	pm_runtime_enable(&card->dev); +		/* +		 * Enable runtime PM for this card +		 */ +		pm_runtime_enable(&card->dev); +	}  	/*  	 * The number of functions on the card is encoded inside @@ -745,16 +1145,16 @@ int mmc_attach_sdio(struct mmc_host *host, u32 ocr)  			goto remove;  		/* -		 * Enable Runtime PM for this func +		 * Enable Runtime PM for this func (if supported)  		 */ -		pm_runtime_enable(&card->sdio_func[i]->dev); +		if (host->caps & MMC_CAP_POWER_OFF_CARD) +			pm_runtime_enable(&card->sdio_func[i]->dev);  	} -	mmc_release_host(host); -  	/*  	 * First add the card to the driver model...  	 */ +	mmc_release_host(host);  	err = mmc_add_card(host->card);  	if (err)  		goto remove_added; @@ -768,6 +1168,7 @@ int mmc_attach_sdio(struct mmc_host *host, u32 ocr)  			goto remove_added;  	} +	mmc_claim_host(host);  	return 0; @@ -777,13 +1178,14 @@ remove_added:  	mmc_claim_host(host);  remove:  	/* And with lock if it hasn't been added. */ +	mmc_release_host(host);  	if (host->card)  		mmc_sdio_remove(host); +	mmc_claim_host(host);  err:  	mmc_detach_bus(host); -	mmc_release_host(host); -	printk(KERN_ERR "%s: error %d whilst initialising SDIO card\n", +	pr_err("%s: error %d whilst initialising SDIO card\n",  		mmc_hostname(host), err);  	return err; diff --git a/drivers/mmc/core/sdio_bus.c b/drivers/mmc/core/sdio_bus.c index 2716c7ab6bb..4fa8fef9147 100644 --- a/drivers/mmc/core/sdio_bus.c +++ b/drivers/mmc/core/sdio_bus.c @@ -13,10 +13,13 @@  #include <linux/device.h>  #include <linux/err.h> +#include <linux/export.h>  #include <linux/slab.h>  #include <linux/pm_runtime.h> +#include <linux/acpi.h>  #include <linux/mmc/card.h> +#include <linux/mmc/host.h>  #include <linux/mmc/sdio_func.h>  #include "sdio_cis.h" @@ -31,7 +34,8 @@ field##_show(struct device *dev, struct device_attribute *attr, char *buf)				\  									\  	func = dev_to_sdio_func (dev);					\  	return sprintf (buf, format_string, func->field);		\ -} +}									\ +static DEVICE_ATTR_RO(field)  sdio_config_attr(class, "0x%02x\n");  sdio_config_attr(vendor, "0x%04x\n"); @@ -44,14 +48,16 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,  	return sprintf(buf, "sdio:c%02Xv%04Xd%04X\n",  			func->class, func->vendor, func->device);  } - -static struct device_attribute sdio_dev_attrs[] = { -	__ATTR_RO(class), -	__ATTR_RO(vendor), -	__ATTR_RO(device), -	__ATTR_RO(modalias), -	__ATTR_NULL, +static DEVICE_ATTR_RO(modalias); + +static struct attribute *sdio_dev_attrs[] = { +	&dev_attr_class.attr, +	&dev_attr_vendor.attr, +	&dev_attr_device.attr, +	&dev_attr_modalias.attr, +	NULL,  }; +ATTRIBUTE_GROUPS(sdio_dev);  static const struct sdio_device_id *sdio_match_one(struct sdio_func *func,  	const struct sdio_device_id *id) @@ -132,9 +138,11 @@ static int sdio_bus_probe(struct device *dev)  	 * it should call pm_runtime_put_noidle() in its probe routine and  	 * pm_runtime_get_noresume() in its remove routine.  	 */ -	ret = pm_runtime_get_sync(dev); -	if (ret < 0) -		goto out; +	if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD) { +		ret = pm_runtime_get_sync(dev); +		if (ret < 0) +			goto disable_runtimepm; +	}  	/* Set the default block size so the driver is sure it's something  	 * sensible. */ @@ -151,8 +159,8 @@ static int sdio_bus_probe(struct device *dev)  	return 0;  disable_runtimepm: -	pm_runtime_put_noidle(dev); -out: +	if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD) +		pm_runtime_put_noidle(dev);  	return ret;  } @@ -160,17 +168,16 @@ static int sdio_bus_remove(struct device *dev)  {  	struct sdio_driver *drv = to_sdio_driver(dev->driver);  	struct sdio_func *func = dev_to_sdio_func(dev); -	int ret; +	int ret = 0;  	/* Make sure card is powered before invoking ->remove() */ -	ret = pm_runtime_get_sync(dev); -	if (ret < 0) -		goto out; +	if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD) +		pm_runtime_get_sync(dev);  	drv->remove(func);  	if (func->irq_handler) { -		printk(KERN_WARNING "WARNING: driver %s did not remove " +		pr_warning("WARNING: driver %s did not remove "  			"its interrupt handler!\n", drv->name);  		sdio_claim_host(func);  		sdio_release_irq(func); @@ -178,65 +185,38 @@ static int sdio_bus_remove(struct device *dev)  	}  	/* First, undo the increment made directly above */ -	pm_runtime_put_noidle(dev); +	if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD) +		pm_runtime_put_noidle(dev);  	/* Then undo the runtime PM settings in sdio_bus_probe() */ -	pm_runtime_put_noidle(dev); +	if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD) +		pm_runtime_put_sync(dev); -out:  	return ret;  } -#ifdef CONFIG_PM_RUNTIME - -static int sdio_bus_pm_prepare(struct device *dev) -{ -	/* -	 * Resume an SDIO device which was suspended at run time at this -	 * point, in order to allow standard SDIO suspend/resume paths -	 * to keep working as usual. -	 * -	 * Ultimately, the SDIO driver itself will decide (in its -	 * suspend handler, or lack thereof) whether the card should be -	 * removed or kept, and if kept, at what power state. -	 * -	 * At this point, PM core have increased our use count, so it's -	 * safe to directly resume the device. After system is resumed -	 * again, PM core will drop back its runtime PM use count, and if -	 * needed device will be suspended again. -	 * -	 * The end result is guaranteed to be a power state that is -	 * coherent with the device's runtime PM use count. -	 * -	 * The return value of pm_runtime_resume is deliberately unchecked -	 * since there is little point in failing system suspend if a -	 * device can't be resumed. -	 */ -	pm_runtime_resume(dev); - -	return 0; -} +#ifdef CONFIG_PM  static const struct dev_pm_ops sdio_bus_pm_ops = { +	SET_SYSTEM_SLEEP_PM_OPS(pm_generic_suspend, pm_generic_resume)  	SET_RUNTIME_PM_OPS(  		pm_generic_runtime_suspend,  		pm_generic_runtime_resume, -		pm_generic_runtime_idle +		NULL  	) -	.prepare = sdio_bus_pm_prepare,  };  #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", -	.dev_attrs	= sdio_dev_attrs, +	.dev_groups	= sdio_dev_groups,  	.match		= sdio_bus_match,  	.uevent		= sdio_bus_uevent,  	.probe		= sdio_bus_probe, @@ -283,8 +263,7 @@ static void sdio_release_func(struct device *dev)  	sdio_free_func_cis(func); -	if (func->info) -		kfree(func->info); +	kfree(func->info);  	kfree(func);  } @@ -311,6 +290,18 @@ struct sdio_func *sdio_alloc_func(struct mmc_card *card)  	return func;  } +#ifdef CONFIG_ACPI +static void sdio_acpi_set_handle(struct sdio_func *func) +{ +	struct mmc_host *host = func->card->host; +	u64 addr = (host->slotno << 16) | func->num; + +	acpi_preset_companion(&func->dev, ACPI_COMPANION(host->parent), addr); +} +#else +static inline void sdio_acpi_set_handle(struct sdio_func *func) {} +#endif +  /*   * Register a new SDIO function with the driver model.   */ @@ -320,9 +311,12 @@ int sdio_add_func(struct sdio_func *func)  	dev_set_name(&func->dev, "%s:%d", mmc_card_id(func->card), func->num); +	sdio_acpi_set_handle(func);  	ret = device_add(&func->dev); -	if (ret == 0) +	if (ret == 0) {  		sdio_func_set_present(func); +		acpi_dev_pm_attach(&func->dev, false); +	}  	return ret;  } @@ -338,6 +332,7 @@ void sdio_remove_func(struct sdio_func *func)  	if (!sdio_func_present(func))  		return; +	acpi_dev_pm_detach(&func->dev, false);  	device_del(&func->dev);  	put_device(&func->dev);  } diff --git a/drivers/mmc/core/sdio_cis.c b/drivers/mmc/core/sdio_cis.c index 541bdb89e0c..8e94e555b78 100644 --- a/drivers/mmc/core/sdio_cis.c +++ b/drivers/mmc/core/sdio_cis.c @@ -132,7 +132,7 @@ static int cis_tpl_parse(struct mmc_card *card, struct sdio_func *func,  			ret = -EINVAL;  		}  		if (ret && ret != -EILSEQ && ret != -ENOENT) { -			printk(KERN_ERR "%s: bad %s tuple 0x%02x (%u bytes)\n", +			pr_err("%s: bad %s tuple 0x%02x (%u bytes)\n",  			       mmc_hostname(card->host), tpl_descr, code, size);  		}  	} else { @@ -313,7 +313,7 @@ static int sdio_read_cis(struct mmc_card *card, struct sdio_func *func)  			if (ret == -ENOENT) {  				/* warn about unknown tuples */ -				printk(KERN_WARNING "%s: queuing unknown" +				pr_warn_ratelimited("%s: queuing unknown"  				       " CIS tuple 0x%02x (%u bytes)\n",  				       mmc_hostname(card->host),  				       tpl_code, tpl_link); diff --git a/drivers/mmc/core/sdio_io.c b/drivers/mmc/core/sdio_io.c index 0f687cdeb06..78cb4d5d9d5 100644 --- a/drivers/mmc/core/sdio_io.c +++ b/drivers/mmc/core/sdio_io.c @@ -9,6 +9,7 @@   * your option) any later version.   */ +#include <linux/export.h>  #include <linux/mmc/host.h>  #include <linux/mmc/card.h>  #include <linux/mmc/sdio.h> @@ -187,14 +188,16 @@ EXPORT_SYMBOL_GPL(sdio_set_block_size);   */  static inline unsigned int sdio_max_byte_size(struct sdio_func *func)  { -	unsigned mval =	min(func->card->host->max_seg_size, -			    func->card->host->max_blk_size); +	unsigned mval =	func->card->host->max_blk_size;  	if (mmc_blksz_for_byte_mode(func->card))  		mval = min(mval, func->cur_blksize);  	else  		mval = min(mval, func->max_blksize); +	if (mmc_card_broken_byte_mode_512(func->card)) +		return min(mval, 511u); +  	return min(mval, 512u); /* maximum size for byte mode */  } @@ -307,13 +310,10 @@ static int sdio_io_rw_ext_helper(struct sdio_func *func, int write,  	/* Do the bulk of the transfer using block mode (if supported). */  	if (func->card->cccr.multi_block && (size > sdio_max_byte_size(func))) {  		/* Blocks per command is limited by host count, host transfer -		 * size (we only use a single sg entry) and the maximum for -		 * IO_RW_EXTENDED of 511 blocks. */ -		max_blocks = min(func->card->host->max_blk_count, -			func->card->host->max_seg_size / func->cur_blksize); -		max_blocks = min(max_blocks, 511u); +		 * size and the maximum for IO_RW_EXTENDED of 511 blocks. */ +		max_blocks = min(func->card->host->max_blk_count, 511u); -		while (remainder > func->cur_blksize) { +		while (remainder >= func->cur_blksize) {  			unsigned blocks;  			blocks = remainder / func->cur_blksize; @@ -338,8 +338,9 @@ static int sdio_io_rw_ext_helper(struct sdio_func *func, int write,  	while (remainder > 0) {  		size = min(remainder, sdio_max_byte_size(func)); +		/* Indicate byte mode by setting "blocks" = 0 */  		ret = mmc_io_rw_extended(func->card, write, func->num, addr, -			 incr_addr, buf, 1, size); +			 incr_addr, buf, 0, size);  		if (ret)  			return ret; diff --git a/drivers/mmc/core/sdio_irq.c b/drivers/mmc/core/sdio_irq.c index bb192f90e8e..5cc13c8d35b 100644 --- a/drivers/mmc/core/sdio_irq.c +++ b/drivers/mmc/core/sdio_irq.c @@ -16,6 +16,7 @@  #include <linux/kernel.h>  #include <linux/sched.h>  #include <linux/kthread.h> +#include <linux/export.h>  #include <linux/wait.h>  #include <linux/delay.h> @@ -27,32 +28,56 @@  #include "sdio_ops.h" -static int process_sdio_pending_irqs(struct mmc_card *card) +static int process_sdio_pending_irqs(struct mmc_host *host)  { +	struct mmc_card *card = host->card;  	int i, ret, count;  	unsigned char pending; +	struct sdio_func *func; + +	/* +	 * Optimization, if there is only 1 function interrupt registered +	 * and we know an IRQ was signaled then call irq handler directly. +	 * Otherwise do the full probe. +	 */ +	func = card->sdio_single_irq; +	if (func && host->sdio_irq_pending) { +		func->irq_handler(func); +		return 1; +	}  	ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_INTx, 0, &pending);  	if (ret) { -		printk(KERN_DEBUG "%s: error %d reading SDIO_CCCR_INTx\n", +		pr_debug("%s: error %d reading SDIO_CCCR_INTx\n",  		       mmc_card_id(card), ret);  		return ret;  	} +	if (pending && mmc_card_broken_irq_polling(card) && +	    !(host->caps & MMC_CAP_SDIO_IRQ)) { +		unsigned char dummy; + +		/* A fake interrupt could be created when we poll SDIO_CCCR_INTx +		 * register with a Marvell SD8797 card. A dummy CMD52 read to +		 * function 0 register 0xff can avoid this. +		 */ +		mmc_io_rw_direct(card, 0, 0, 0xff, 0, &dummy); +	} +  	count = 0;  	for (i = 1; i <= 7; i++) {  		if (pending & (1 << i)) { -			struct sdio_func *func = card->sdio_func[i - 1]; +			func = card->sdio_func[i - 1];  			if (!func) { -				printk(KERN_WARNING "%s: pending IRQ for " -					"non-existant function\n", +				pr_warning("%s: pending IRQ for " +					"non-existent function\n",  					mmc_card_id(card));  				ret = -EINVAL;  			} else if (func->irq_handler) {  				func->irq_handler(func);  				count++;  			} else { -				printk(KERN_WARNING "%s: pending IRQ with no handler\n", +				pr_warning("%s: pending IRQ with no handler\n",  				       sdio_func_id(func));  				ret = -EINVAL;  			} @@ -65,6 +90,15 @@ static int process_sdio_pending_irqs(struct mmc_card *card)  	return ret;  } +void sdio_run_irqs(struct mmc_host *host) +{ +	mmc_claim_host(host); +	host->sdio_irq_pending = true; +	process_sdio_pending_irqs(host); +	mmc_release_host(host); +} +EXPORT_SYMBOL_GPL(sdio_run_irqs); +  static int sdio_irq_thread(void *_host)  {  	struct mmc_host *host = _host; @@ -104,7 +138,8 @@ static int sdio_irq_thread(void *_host)  		ret = __mmc_claim_host(host, &host->sdio_irq_thread_abort);  		if (ret)  			break; -		ret = process_sdio_pending_irqs(host->card); +		ret = process_sdio_pending_irqs(host); +		host->sdio_irq_pending = false;  		mmc_release_host(host);  		/* @@ -134,15 +169,21 @@ static int sdio_irq_thread(void *_host)  		}  		set_current_state(TASK_INTERRUPTIBLE); -		if (host->caps & MMC_CAP_SDIO_IRQ) +		if (host->caps & MMC_CAP_SDIO_IRQ) { +			mmc_host_clk_hold(host);  			host->ops->enable_sdio_irq(host, 1); +			mmc_host_clk_release(host); +		}  		if (!kthread_should_stop())  			schedule_timeout(period);  		set_current_state(TASK_RUNNING);  	} while (!kthread_should_stop()); -	if (host->caps & MMC_CAP_SDIO_IRQ) +	if (host->caps & MMC_CAP_SDIO_IRQ) { +		mmc_host_clk_hold(host);  		host->ops->enable_sdio_irq(host, 0); +		mmc_host_clk_release(host); +	}  	pr_debug("%s: IRQ thread exiting with code %d\n",  		 mmc_hostname(host), ret); @@ -157,14 +198,20 @@ static int sdio_card_irq_get(struct mmc_card *card)  	WARN_ON(!host->claimed);  	if (!host->sdio_irqs++) { -		atomic_set(&host->sdio_irq_thread_abort, 0); -		host->sdio_irq_thread = -			kthread_run(sdio_irq_thread, host, "ksdioirqd/%s", -				mmc_hostname(host)); -		if (IS_ERR(host->sdio_irq_thread)) { -			int err = PTR_ERR(host->sdio_irq_thread); -			host->sdio_irqs--; -			return err; +		if (!(host->caps2 & MMC_CAP2_SDIO_IRQ_NOTHREAD)) { +			atomic_set(&host->sdio_irq_thread_abort, 0); +			host->sdio_irq_thread = +				kthread_run(sdio_irq_thread, host, +					    "ksdioirqd/%s", mmc_hostname(host)); +			if (IS_ERR(host->sdio_irq_thread)) { +				int err = PTR_ERR(host->sdio_irq_thread); +				host->sdio_irqs--; +				return err; +			} +		} else { +			mmc_host_clk_hold(host); +			host->ops->enable_sdio_irq(host, 1); +			mmc_host_clk_release(host);  		}  	} @@ -179,13 +226,37 @@ static int sdio_card_irq_put(struct mmc_card *card)  	BUG_ON(host->sdio_irqs < 1);  	if (!--host->sdio_irqs) { -		atomic_set(&host->sdio_irq_thread_abort, 1); -		kthread_stop(host->sdio_irq_thread); +		if (!(host->caps2 & MMC_CAP2_SDIO_IRQ_NOTHREAD)) { +			atomic_set(&host->sdio_irq_thread_abort, 1); +			kthread_stop(host->sdio_irq_thread); +		} else { +			mmc_host_clk_hold(host); +			host->ops->enable_sdio_irq(host, 0); +			mmc_host_clk_release(host); +		}  	}  	return 0;  } +/* If there is only 1 function registered set sdio_single_irq */ +static void sdio_single_irq_set(struct mmc_card *card) +{ +	struct sdio_func *func; +	int i; + +	card->sdio_single_irq = NULL; +	if ((card->host->caps & MMC_CAP_SDIO_IRQ) && +	    card->host->sdio_irqs == 1) +		for (i = 0; i < card->sdio_funcs; i++) { +		       func = card->sdio_func[i]; +		       if (func && func->irq_handler) { +			       card->sdio_single_irq = func; +			       break; +		       } +	       } +} +  /**   *	sdio_claim_irq - claim the IRQ for a SDIO function   *	@func: SDIO function @@ -227,6 +298,7 @@ int sdio_claim_irq(struct sdio_func *func, sdio_irq_handler_t *handler)  	ret = sdio_card_irq_get(func->card);  	if (ret)  		func->irq_handler = NULL; +	sdio_single_irq_set(func->card);  	return ret;  } @@ -251,6 +323,7 @@ int sdio_release_irq(struct sdio_func *func)  	if (func->irq_handler) {  		func->irq_handler = NULL;  		sdio_card_irq_put(func->card); +		sdio_single_irq_set(func->card);  	}  	ret = mmc_io_rw_direct(func->card, 0, 0, SDIO_CCCR_IENx, 0, ®); diff --git a/drivers/mmc/core/sdio_ops.c b/drivers/mmc/core/sdio_ops.c index dea36d9c22e..62508b457c4 100644 --- a/drivers/mmc/core/sdio_ops.c +++ b/drivers/mmc/core/sdio_ops.c @@ -21,13 +21,11 @@  int mmc_send_io_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr)  { -	struct mmc_command cmd; +	struct mmc_command cmd = {0};  	int i, err = 0;  	BUG_ON(!host); -	memset(&cmd, 0, sizeof(struct mmc_command)); -  	cmd.opcode = SD_IO_SEND_OP_COND;  	cmd.arg = ocr;  	cmd.flags = MMC_RSP_SPI_R4 | MMC_RSP_R4 | MMC_CMD_BCR; @@ -70,7 +68,7 @@ int mmc_send_io_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr)  static int mmc_io_rw_direct_host(struct mmc_host *host, int write, unsigned fn,  	unsigned addr, u8 in, u8 *out)  { -	struct mmc_command cmd; +	struct mmc_command cmd = {0};  	int err;  	BUG_ON(!host); @@ -80,8 +78,6 @@ static int mmc_io_rw_direct_host(struct mmc_host *host, int write, unsigned fn,  	if (addr & ~0x1FFFF)  		return -EINVAL; -	memset(&cmd, 0, sizeof(struct mmc_command)); -  	cmd.opcode = SD_IO_RW_DIRECT;  	cmd.arg = write ? 0x80000000 : 0x00000000;  	cmd.arg |= fn << 28; @@ -125,25 +121,22 @@ int mmc_io_rw_direct(struct mmc_card *card, int write, unsigned fn,  int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn,  	unsigned addr, int incr_addr, u8 *buf, unsigned blocks, unsigned blksz)  { -	struct mmc_request mrq; -	struct mmc_command cmd; -	struct mmc_data data; -	struct scatterlist sg; +	struct mmc_request mrq = {NULL}; +	struct mmc_command cmd = {0}; +	struct mmc_data data = {0}; +	struct scatterlist sg, *sg_ptr; +	struct sg_table sgtable; +	unsigned int nents, left_size, i; +	unsigned int seg_size = card->host->max_seg_size;  	BUG_ON(!card);  	BUG_ON(fn > 7); -	BUG_ON(blocks == 1 && blksz > 512); -	WARN_ON(blocks == 0);  	WARN_ON(blksz == 0);  	/* sanity check */  	if (addr & ~0x1FFFF)  		return -EINVAL; -	memset(&mrq, 0, sizeof(struct mmc_request)); -	memset(&cmd, 0, sizeof(struct mmc_command)); -	memset(&data, 0, sizeof(struct mmc_data)); -  	mrq.cmd = &cmd;  	mrq.data = &data; @@ -152,24 +145,46 @@ int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn,  	cmd.arg |= fn << 28;  	cmd.arg |= incr_addr ? 0x04000000 : 0x00000000;  	cmd.arg |= addr << 9; -	if (blocks == 1 && blksz <= 512) +	if (blocks == 0)  		cmd.arg |= (blksz == 512) ? 0 : blksz;	/* byte mode */  	else  		cmd.arg |= 0x08000000 | blocks;		/* block mode */  	cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_ADTC;  	data.blksz = blksz; -	data.blocks = blocks; +	/* Code in host drivers/fwk assumes that "blocks" always is >=1 */ +	data.blocks = blocks ? blocks : 1;  	data.flags = write ? MMC_DATA_WRITE : MMC_DATA_READ; -	data.sg = &sg; -	data.sg_len = 1; -	sg_init_one(&sg, buf, blksz * blocks); +	left_size = data.blksz * data.blocks; +	nents = (left_size - 1) / seg_size + 1; +	if (nents > 1) { +		if (sg_alloc_table(&sgtable, nents, GFP_KERNEL)) +			return -ENOMEM; + +		data.sg = sgtable.sgl; +		data.sg_len = nents; + +		for_each_sg(data.sg, sg_ptr, data.sg_len, i) { +			sg_set_page(sg_ptr, virt_to_page(buf + (i * seg_size)), +					min(seg_size, left_size), +					offset_in_page(buf + (i * seg_size))); +			left_size = left_size - seg_size; +		} +	} else { +		data.sg = &sg; +		data.sg_len = 1; + +		sg_init_one(&sg, buf, left_size); +	}  	mmc_set_data_timeout(&data, card);  	mmc_wait_for_req(card->host, &mrq); +	if (nents > 1) +		sg_free_table(&sgtable); +  	if (cmd.error)  		return cmd.error;  	if (data.error) diff --git a/drivers/mmc/core/slot-gpio.c b/drivers/mmc/core/slot-gpio.c new file mode 100644 index 00000000000..5f89cb83d5f --- /dev/null +++ b/drivers/mmc/core/slot-gpio.c @@ -0,0 +1,355 @@ +/* + * Generic GPIO card-detect helper + * + * Copyright (C) 2011, Guennadi Liakhovetski <g.liakhovetski@gmx.de> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/err.h> +#include <linux/gpio.h> +#include <linux/gpio/consumer.h> +#include <linux/interrupt.h> +#include <linux/jiffies.h> +#include <linux/mmc/host.h> +#include <linux/mmc/slot-gpio.h> +#include <linux/module.h> +#include <linux/slab.h> + +struct mmc_gpio { +	struct gpio_desc *ro_gpio; +	struct gpio_desc *cd_gpio; +	bool override_ro_active_level; +	bool override_cd_active_level; +	char *ro_label; +	char cd_label[0]; +}; + +static irqreturn_t mmc_gpio_cd_irqt(int irq, void *dev_id) +{ +	/* Schedule a card detection after a debounce timeout */ +	struct mmc_host *host = dev_id; + +	host->trigger_card_event = true; +	mmc_detect_change(host, msecs_to_jiffies(200)); + +	return IRQ_HANDLED; +} + +static int mmc_gpio_alloc(struct mmc_host *host) +{ +	size_t len = strlen(dev_name(host->parent)) + 4; +	struct mmc_gpio *ctx; + +	mutex_lock(&host->slot.lock); + +	ctx = host->slot.handler_priv; +	if (!ctx) { +		/* +		 * devm_kzalloc() can be called after device_initialize(), even +		 * before device_add(), i.e., between mmc_alloc_host() and +		 * mmc_add_host() +		 */ +		ctx = devm_kzalloc(&host->class_dev, sizeof(*ctx) + 2 * len, +				   GFP_KERNEL); +		if (ctx) { +			ctx->ro_label = ctx->cd_label + len; +			snprintf(ctx->cd_label, len, "%s cd", dev_name(host->parent)); +			snprintf(ctx->ro_label, len, "%s ro", dev_name(host->parent)); +			host->slot.handler_priv = ctx; +		} +	} + +	mutex_unlock(&host->slot.lock); + +	return ctx ? 0 : -ENOMEM; +} + +int mmc_gpio_get_ro(struct mmc_host *host) +{ +	struct mmc_gpio *ctx = host->slot.handler_priv; + +	if (!ctx || !ctx->ro_gpio) +		return -ENOSYS; + +	if (ctx->override_ro_active_level) +		return !gpiod_get_raw_value_cansleep(ctx->ro_gpio) ^ +			!!(host->caps2 & MMC_CAP2_RO_ACTIVE_HIGH); + +	return gpiod_get_value_cansleep(ctx->ro_gpio); +} +EXPORT_SYMBOL(mmc_gpio_get_ro); + +int mmc_gpio_get_cd(struct mmc_host *host) +{ +	struct mmc_gpio *ctx = host->slot.handler_priv; + +	if (!ctx || !ctx->cd_gpio) +		return -ENOSYS; + +	if (ctx->override_cd_active_level) +		return !gpiod_get_raw_value_cansleep(ctx->cd_gpio) ^ +			!!(host->caps2 & MMC_CAP2_CD_ACTIVE_HIGH); + +	return gpiod_get_value_cansleep(ctx->cd_gpio); +} +EXPORT_SYMBOL(mmc_gpio_get_cd); + +/** + * mmc_gpio_request_ro - request a gpio for write-protection + * @host: mmc host + * @gpio: gpio number requested + * + * As devm_* managed functions are used in mmc_gpio_request_ro(), client + * drivers do not need to explicitly call mmc_gpio_free_ro() for freeing up, + * if the requesting and freeing are only needed at probing and unbinding time + * for once.  However, if client drivers do something special like runtime + * switching for write-protection, they are responsible for calling + * mmc_gpio_request_ro() and mmc_gpio_free_ro() as a pair on their own. + * + * Returns zero on success, else an error. + */ +int mmc_gpio_request_ro(struct mmc_host *host, unsigned int gpio) +{ +	struct mmc_gpio *ctx; +	int ret; + +	if (!gpio_is_valid(gpio)) +		return -EINVAL; + +	ret = mmc_gpio_alloc(host); +	if (ret < 0) +		return ret; + +	ctx = host->slot.handler_priv; + +	ret = devm_gpio_request_one(&host->class_dev, gpio, GPIOF_DIR_IN, +				    ctx->ro_label); +	if (ret < 0) +		return ret; + +	ctx->override_ro_active_level = true; +	ctx->ro_gpio = gpio_to_desc(gpio); + +	return 0; +} +EXPORT_SYMBOL(mmc_gpio_request_ro); + +void mmc_gpiod_request_cd_irq(struct mmc_host *host) +{ +	struct mmc_gpio *ctx = host->slot.handler_priv; +	int ret, irq; + +	if (host->slot.cd_irq >= 0 || !ctx || !ctx->cd_gpio) +		return; + +	irq = gpiod_to_irq(ctx->cd_gpio); + +	/* +	 * Even if gpiod_to_irq() returns a valid IRQ number, the platform might +	 * still prefer to poll, e.g., because that IRQ number is already used +	 * by another unit and cannot be shared. +	 */ +	if (irq >= 0 && host->caps & MMC_CAP_NEEDS_POLL) +		irq = -EINVAL; + +	if (irq >= 0) { +		ret = devm_request_threaded_irq(&host->class_dev, irq, +			NULL, mmc_gpio_cd_irqt, +			IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, +			ctx->cd_label, host); +		if (ret < 0) +			irq = ret; +	} + +	host->slot.cd_irq = irq; + +	if (irq < 0) +		host->caps |= MMC_CAP_NEEDS_POLL; +} +EXPORT_SYMBOL(mmc_gpiod_request_cd_irq); + +/** + * mmc_gpio_request_cd - request a gpio for card-detection + * @host: mmc host + * @gpio: gpio number requested + * @debounce: debounce time in microseconds + * + * As devm_* managed functions are used in mmc_gpio_request_cd(), client + * drivers do not need to explicitly call mmc_gpio_free_cd() for freeing up, + * if the requesting and freeing are only needed at probing and unbinding time + * for once.  However, if client drivers do something special like runtime + * switching for card-detection, they are responsible for calling + * mmc_gpio_request_cd() and mmc_gpio_free_cd() as a pair on their own. + * + * If GPIO debouncing is desired, set the debounce parameter to a non-zero + * value. The caller is responsible for ensuring that the GPIO driver associated + * with the GPIO supports debouncing, otherwise an error will be returned. + * + * Returns zero on success, else an error. + */ +int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio, +			unsigned int debounce) +{ +	struct mmc_gpio *ctx; +	int ret; + +	ret = mmc_gpio_alloc(host); +	if (ret < 0) +		return ret; + +	ctx = host->slot.handler_priv; + +	ret = devm_gpio_request_one(&host->class_dev, gpio, GPIOF_DIR_IN, +				    ctx->cd_label); +	if (ret < 0) +		/* +		 * don't bother freeing memory. It might still get used by other +		 * slot functions, in any case it will be freed, when the device +		 * is destroyed. +		 */ +		return ret; + +	if (debounce) { +		ret = gpio_set_debounce(gpio, debounce); +		if (ret < 0) +			return ret; +	} + +	ctx->override_cd_active_level = true; +	ctx->cd_gpio = gpio_to_desc(gpio); + +	mmc_gpiod_request_cd_irq(host); + +	return 0; +} +EXPORT_SYMBOL(mmc_gpio_request_cd); + +/** + * mmc_gpio_free_ro - free the write-protection gpio + * @host: mmc host + * + * It's provided only for cases that client drivers need to manually free + * up the write-protection gpio requested by mmc_gpio_request_ro(). + */ +void mmc_gpio_free_ro(struct mmc_host *host) +{ +	struct mmc_gpio *ctx = host->slot.handler_priv; +	int gpio; + +	if (!ctx || !ctx->ro_gpio) +		return; + +	gpio = desc_to_gpio(ctx->ro_gpio); +	ctx->ro_gpio = NULL; + +	devm_gpio_free(&host->class_dev, gpio); +} +EXPORT_SYMBOL(mmc_gpio_free_ro); + +/** + * mmc_gpio_free_cd - free the card-detection gpio + * @host: mmc host + * + * It's provided only for cases that client drivers need to manually free + * up the card-detection gpio requested by mmc_gpio_request_cd(). + */ +void mmc_gpio_free_cd(struct mmc_host *host) +{ +	struct mmc_gpio *ctx = host->slot.handler_priv; +	int gpio; + +	if (!ctx || !ctx->cd_gpio) +		return; + +	if (host->slot.cd_irq >= 0) { +		devm_free_irq(&host->class_dev, host->slot.cd_irq, host); +		host->slot.cd_irq = -EINVAL; +	} + +	gpio = desc_to_gpio(ctx->cd_gpio); +	ctx->cd_gpio = NULL; + +	devm_gpio_free(&host->class_dev, gpio); +} +EXPORT_SYMBOL(mmc_gpio_free_cd); + +/** + * mmc_gpiod_request_cd - request a gpio descriptor for card-detection + * @host: mmc host + * @con_id: function within the GPIO consumer + * @idx: index of the GPIO to obtain in the consumer + * @override_active_level: ignore %GPIO_ACTIVE_LOW flag + * @debounce: debounce time in microseconds + * + * Use this function in place of mmc_gpio_request_cd() to use the GPIO + * descriptor API.  Note that it is paired with mmc_gpiod_free_cd() not + * mmc_gpio_free_cd().  Note also that it must be called prior to mmc_add_host() + * otherwise the caller must also call mmc_gpiod_request_cd_irq(). + * + * Returns zero on success, else an error. + */ +int mmc_gpiod_request_cd(struct mmc_host *host, const char *con_id, +			 unsigned int idx, bool override_active_level, +			 unsigned int debounce) +{ +	struct mmc_gpio *ctx; +	struct gpio_desc *desc; +	int ret; + +	ret = mmc_gpio_alloc(host); +	if (ret < 0) +		return ret; + +	ctx = host->slot.handler_priv; + +	if (!con_id) +		con_id = ctx->cd_label; + +	desc = devm_gpiod_get_index(host->parent, con_id, idx); +	if (IS_ERR(desc)) +		return PTR_ERR(desc); + +	ret = gpiod_direction_input(desc); +	if (ret < 0) +		return ret; + +	if (debounce) { +		ret = gpiod_set_debounce(desc, debounce); +		if (ret < 0) +			return ret; +	} + +	ctx->override_cd_active_level = override_active_level; +	ctx->cd_gpio = desc; + +	return 0; +} +EXPORT_SYMBOL(mmc_gpiod_request_cd); + +/** + * mmc_gpiod_free_cd - free the card-detection gpio descriptor + * @host: mmc host + * + * It's provided only for cases that client drivers need to manually free + * up the card-detection gpio requested by mmc_gpiod_request_cd(). + */ +void mmc_gpiod_free_cd(struct mmc_host *host) +{ +	struct mmc_gpio *ctx = host->slot.handler_priv; + +	if (!ctx || !ctx->cd_gpio) +		return; + +	if (host->slot.cd_irq >= 0) { +		devm_free_irq(&host->class_dev, host->slot.cd_irq, host); +		host->slot.cd_irq = -EINVAL; +	} + +	devm_gpiod_put(&host->class_dev, ctx->cd_gpio); + +	ctx->cd_gpio = NULL; +} +EXPORT_SYMBOL(mmc_gpiod_free_cd);  | 
