diff options
Diffstat (limited to 'drivers/mmc/core')
| -rw-r--r-- | drivers/mmc/core/block.c | 67 | ||||
| -rw-r--r-- | drivers/mmc/core/bus.c | 3 | ||||
| -rw-r--r-- | drivers/mmc/core/card.h | 2 | ||||
| -rw-r--r-- | drivers/mmc/core/debugfs.c | 1 | ||||
| -rw-r--r-- | drivers/mmc/core/mmc.c | 6 | ||||
| -rw-r--r-- | drivers/mmc/core/quirks.h | 8 | ||||
| -rw-r--r-- | drivers/mmc/core/sd.c | 2 | 
7 files changed, 77 insertions, 12 deletions
| diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c index ea80ff4cd7f9..ccfa98af1dd3 100644 --- a/drivers/mmc/core/block.c +++ b/drivers/mmc/core/block.c @@ -122,6 +122,10 @@ struct mmc_blk_data {  	struct device_attribute force_ro;  	struct device_attribute power_ro_lock;  	int	area_type; + +	/* debugfs files (only in main mmc_blk_data) */ +	struct dentry *status_dentry; +	struct dentry *ext_csd_dentry;  };  /* Device type for RPMB character devices */ @@ -233,9 +237,14 @@ static ssize_t power_ro_lock_store(struct device *dev,  	/* Dispatch locking to the block layer */  	req = blk_get_request(mq->queue, REQ_OP_DRV_OUT, __GFP_RECLAIM); +	if (IS_ERR(req)) { +		count = PTR_ERR(req); +		goto out_put; +	}  	req_to_mmc_queue_req(req)->drv_op = MMC_DRV_OP_BOOT_WP;  	blk_execute_rq(mq->queue, NULL, req, 0);  	ret = req_to_mmc_queue_req(req)->drv_op_result; +	blk_put_request(req);  	if (!ret) {  		pr_info("%s: Locking boot partition ro until next power on\n", @@ -248,7 +257,7 @@ static ssize_t power_ro_lock_store(struct device *dev,  				set_disk_ro(part_md->disk, 1);  			}  	} - +out_put:  	mmc_blk_put(md);  	return count;  } @@ -624,6 +633,10 @@ static int mmc_blk_ioctl_cmd(struct mmc_blk_data *md,  	req = blk_get_request(mq->queue,  		idata->ic.write_flag ? REQ_OP_DRV_OUT : REQ_OP_DRV_IN,  		__GFP_RECLAIM); +	if (IS_ERR(req)) { +		err = PTR_ERR(req); +		goto cmd_done; +	}  	idatas[0] = idata;  	req_to_mmc_queue_req(req)->drv_op =  		rpmb ? MMC_DRV_OP_IOCTL_RPMB : MMC_DRV_OP_IOCTL; @@ -691,6 +704,10 @@ static int mmc_blk_ioctl_multi_cmd(struct mmc_blk_data *md,  	req = blk_get_request(mq->queue,  		idata[0]->ic.write_flag ? REQ_OP_DRV_OUT : REQ_OP_DRV_IN,  		__GFP_RECLAIM); +	if (IS_ERR(req)) { +		err = PTR_ERR(req); +		goto cmd_err; +	}  	req_to_mmc_queue_req(req)->drv_op =  		rpmb ? MMC_DRV_OP_IOCTL_RPMB : MMC_DRV_OP_IOCTL;  	req_to_mmc_queue_req(req)->drv_op_data = idata; @@ -2550,6 +2567,8 @@ static int mmc_dbg_card_status_get(void *data, u64 *val)  	/* Ask the block layer about the card status */  	req = blk_get_request(mq->queue, REQ_OP_DRV_IN, __GFP_RECLAIM); +	if (IS_ERR(req)) +		return PTR_ERR(req);  	req_to_mmc_queue_req(req)->drv_op = MMC_DRV_OP_GET_CARD_STATUS;  	blk_execute_rq(mq->queue, NULL, req, 0);  	ret = req_to_mmc_queue_req(req)->drv_op_result; @@ -2557,6 +2576,7 @@ static int mmc_dbg_card_status_get(void *data, u64 *val)  		*val = ret;  		ret = 0;  	} +	blk_put_request(req);  	return ret;  } @@ -2583,10 +2603,15 @@ static int mmc_ext_csd_open(struct inode *inode, struct file *filp)  	/* Ask the block layer for the EXT CSD */  	req = blk_get_request(mq->queue, REQ_OP_DRV_IN, __GFP_RECLAIM); +	if (IS_ERR(req)) { +		err = PTR_ERR(req); +		goto out_free; +	}  	req_to_mmc_queue_req(req)->drv_op = MMC_DRV_OP_GET_EXT_CSD;  	req_to_mmc_queue_req(req)->drv_op_data = &ext_csd;  	blk_execute_rq(mq->queue, NULL, req, 0);  	err = req_to_mmc_queue_req(req)->drv_op_result; +	blk_put_request(req);  	if (err) {  		pr_err("FAILED %d\n", err);  		goto out_free; @@ -2632,7 +2657,7 @@ static const struct file_operations mmc_dbg_ext_csd_fops = {  	.llseek		= default_llseek,  }; -static int mmc_blk_add_debugfs(struct mmc_card *card) +static int mmc_blk_add_debugfs(struct mmc_card *card, struct mmc_blk_data *md)  {  	struct dentry *root; @@ -2642,28 +2667,53 @@ static int mmc_blk_add_debugfs(struct mmc_card *card)  	root = card->debugfs_root;  	if (mmc_card_mmc(card) || mmc_card_sd(card)) { -		if (!debugfs_create_file("status", S_IRUSR, root, card, -					 &mmc_dbg_card_status_fops)) +		md->status_dentry = +			debugfs_create_file("status", S_IRUSR, root, card, +					    &mmc_dbg_card_status_fops); +		if (!md->status_dentry)  			return -EIO;  	}  	if (mmc_card_mmc(card)) { -		if (!debugfs_create_file("ext_csd", S_IRUSR, root, card, -					 &mmc_dbg_ext_csd_fops)) +		md->ext_csd_dentry = +			debugfs_create_file("ext_csd", S_IRUSR, root, card, +					    &mmc_dbg_ext_csd_fops); +		if (!md->ext_csd_dentry)  			return -EIO;  	}  	return 0;  } +static void mmc_blk_remove_debugfs(struct mmc_card *card, +				   struct mmc_blk_data *md) +{ +	if (!card->debugfs_root) +		return; + +	if (!IS_ERR_OR_NULL(md->status_dentry)) { +		debugfs_remove(md->status_dentry); +		md->status_dentry = NULL; +	} + +	if (!IS_ERR_OR_NULL(md->ext_csd_dentry)) { +		debugfs_remove(md->ext_csd_dentry); +		md->ext_csd_dentry = NULL; +	} +}  #else -static int mmc_blk_add_debugfs(struct mmc_card *card) +static int mmc_blk_add_debugfs(struct mmc_card *card, struct mmc_blk_data *md)  {  	return 0;  } +static void mmc_blk_remove_debugfs(struct mmc_card *card, +				   struct mmc_blk_data *md) +{ +} +  #endif /* CONFIG_DEBUG_FS */  static int mmc_blk_probe(struct mmc_card *card) @@ -2703,7 +2753,7 @@ static int mmc_blk_probe(struct mmc_card *card)  	}  	/* Add two debugfs entries */ -	mmc_blk_add_debugfs(card); +	mmc_blk_add_debugfs(card, md);  	pm_runtime_set_autosuspend_delay(&card->dev, 3000);  	pm_runtime_use_autosuspend(&card->dev); @@ -2729,6 +2779,7 @@ static void mmc_blk_remove(struct mmc_card *card)  {  	struct mmc_blk_data *md = dev_get_drvdata(&card->dev); +	mmc_blk_remove_debugfs(card, md);  	mmc_blk_remove_parts(card, md);  	pm_runtime_get_sync(&card->dev);  	mmc_claim_host(card->host); diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c index a4b49e25fe96..7586ff2ad1f1 100644 --- a/drivers/mmc/core/bus.c +++ b/drivers/mmc/core/bus.c @@ -157,6 +157,9 @@ static int mmc_bus_suspend(struct device *dev)  		return ret;  	ret = host->bus_ops->suspend(host); +	if (ret) +		pm_generic_resume(dev); +  	return ret;  } diff --git a/drivers/mmc/core/card.h b/drivers/mmc/core/card.h index f06cd91964ce..79a5b985ccf5 100644 --- a/drivers/mmc/core/card.h +++ b/drivers/mmc/core/card.h @@ -75,9 +75,11 @@ struct mmc_fixup {  #define EXT_CSD_REV_ANY (-1u)  #define CID_MANFID_SANDISK      0x2 +#define CID_MANFID_ATP          0x9  #define CID_MANFID_TOSHIBA      0x11  #define CID_MANFID_MICRON       0x13  #define CID_MANFID_SAMSUNG      0x15 +#define CID_MANFID_APACER       0x27  #define CID_MANFID_KINGSTON     0x70  #define CID_MANFID_HYNIX	0x90 diff --git a/drivers/mmc/core/debugfs.c b/drivers/mmc/core/debugfs.c index 01e459a34f33..0f4a7d7b2626 100644 --- a/drivers/mmc/core/debugfs.c +++ b/drivers/mmc/core/debugfs.c @@ -314,4 +314,5 @@ err:  void mmc_remove_card_debugfs(struct mmc_card *card)  {  	debugfs_remove_recursive(card->debugfs_root); +	card->debugfs_root = NULL;  } diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index a552f61060d2..208a762b87ef 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -781,7 +781,7 @@ 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(rev, "0x%x\n", card->ext_csd.rev); -MMC_DEV_ATTR(pre_eol_info, "%02x\n", card->ext_csd.pre_eol_info); +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); @@ -791,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, @@ -1290,7 +1290,7 @@ 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 | diff --git a/drivers/mmc/core/quirks.h b/drivers/mmc/core/quirks.h index f664e9cbc9f8..75d317623852 100644 --- a/drivers/mmc/core/quirks.h +++ b/drivers/mmc/core/quirks.h @@ -53,6 +53,14 @@ static const struct mmc_fixup mmc_blk_fixups[] = {  		  MMC_QUIRK_BLK_NO_CMD23),  	/* +	 * Some SD cards lockup while using CMD23 multiblock transfers. +	 */ +	MMC_FIXUP("AF SD", CID_MANFID_ATP, CID_OEMID_ANY, add_quirk_sd, +		  MMC_QUIRK_BLK_NO_CMD23), +	MMC_FIXUP("APUSD", CID_MANFID_APACER, 0x5048, add_quirk_sd, +		  MMC_QUIRK_BLK_NO_CMD23), + +	/*  	 * Some MMC cards need longer data read timeout than indicated in CSD.  	 */  	MMC_FIXUP(CID_NAME_ANY, CID_MANFID_MICRON, 0x200, add_quirk_mmc, diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index 45bf78f32716..62b84dd8f9fe 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c @@ -675,7 +675,7 @@ 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(serial, "0x%08x\n", card->cid.serial); -MMC_DEV_ATTR(ocr, "%08x\n", card->ocr); +MMC_DEV_ATTR(ocr, "0x%08x\n", card->ocr);  static ssize_t mmc_dsr_show(struct device *dev, |