diff options
Diffstat (limited to 'drivers/mmc/core/mmc.c')
| -rw-r--r-- | drivers/mmc/core/mmc.c | 52 | 
1 files changed, 44 insertions, 8 deletions
| diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 36217ad5e9b1..208a762b87ef 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -780,7 +780,8 @@ 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(pre_eol_info, "%02x\n", card->ext_csd.pre_eol_info); +MMC_DEV_ATTR(rev, "0x%x\n", card->ext_csd.rev); +MMC_DEV_ATTR(pre_eol_info, "0x%02x\n", card->ext_csd.pre_eol_info);  MMC_DEV_ATTR(life_time, "0x%02x 0x%02x\n",  	card->ext_csd.device_life_time_est_typ_a,  	card->ext_csd.device_life_time_est_typ_b); @@ -790,7 +791,7 @@ MMC_DEV_ATTR(enhanced_area_offset, "%llu\n",  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); -MMC_DEV_ATTR(ocr, "%08x\n", card->ocr); +MMC_DEV_ATTR(ocr, "0x%08x\n", card->ocr);  MMC_DEV_ATTR(cmdq_en, "%d\n", card->ext_csd.cmdq_en);  static ssize_t mmc_fwrev_show(struct device *dev, @@ -838,6 +839,7 @@ static struct attribute *mmc_std_attrs[] = {  	&dev_attr_name.attr,  	&dev_attr_oemid.attr,  	&dev_attr_prv.attr, +	&dev_attr_rev.attr,  	&dev_attr_pre_eol_info.attr,  	&dev_attr_life_time.attr,  	&dev_attr_serial.attr, @@ -1288,14 +1290,19 @@ out_err:  static void mmc_select_driver_type(struct mmc_card *card)  { -	int card_drv_type, drive_strength, drv_type; +	int card_drv_type, drive_strength, drv_type = 0; +	int fixed_drv_type = card->host->fixed_drv_type;  	card_drv_type = card->ext_csd.raw_driver_strength |  			mmc_driver_type_mask(0); -	drive_strength = mmc_select_drive_strength(card, -						   card->ext_csd.hs200_max_dtr, -						   card_drv_type, &drv_type); +	if (fixed_drv_type >= 0) +		drive_strength = card_drv_type & mmc_driver_type_mask(fixed_drv_type) +				 ? fixed_drv_type : 0; +	else +		drive_strength = mmc_select_drive_strength(card, +							   card->ext_csd.hs200_max_dtr, +							   card_drv_type, &drv_type);  	card->drive_strength = drive_strength; @@ -1786,12 +1793,41 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,  	}  	/* +	 * Enable Command Queue if supported. Note that Packed Commands cannot +	 * be used with Command Queue. +	 */ +	card->ext_csd.cmdq_en = false; +	if (card->ext_csd.cmdq_support && host->caps2 & MMC_CAP2_CQE) { +		err = mmc_cmdq_enable(card); +		if (err && err != -EBADMSG) +			goto free_card; +		if (err) { +			pr_warn("%s: Enabling CMDQ failed\n", +				mmc_hostname(card->host)); +			card->ext_csd.cmdq_support = false; +			card->ext_csd.cmdq_depth = 0; +			err = 0; +		} +	} +	/*  	 * In some cases (e.g. RPMB or mmc_test), the Command Queue must be  	 * disabled for a time, so a flag is needed to indicate to re-enable the  	 * Command Queue.  	 */  	card->reenable_cmdq = card->ext_csd.cmdq_en; +	if (card->ext_csd.cmdq_en && !host->cqe_enabled) { +		err = host->cqe_ops->cqe_enable(host, card); +		if (err) { +			pr_err("%s: Failed to enable CQE, error %d\n", +				mmc_hostname(host), err); +		} else { +			host->cqe_enabled = true; +			pr_info("%s: Command Queue Engine enabled\n", +				mmc_hostname(host)); +		} +	} +  	if (!oldcard)  		host->card = card; @@ -1911,14 +1947,14 @@ static void mmc_detect(struct mmc_host *host)  {  	int err; -	mmc_get_card(host->card); +	mmc_get_card(host->card, NULL);  	/*  	 * Just check if our card has been removed.  	 */  	err = _mmc_detect_card_removed(host); -	mmc_put_card(host->card); +	mmc_put_card(host->card, NULL);  	if (err) {  		mmc_remove(host); |