Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3c1c4ddf authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull MMC fixes from Ulf Hansson:
 "MMC core:
   - Ensure that debugfs files are removed properly
   - Fix missing blk_put_request()
   - Deal with errors from blk_get_request()
   - Rewind mmc bus suspend operations at failures
   - Prepend '0x' to ocr and pre_eol_info in sysfs to identify as hex

  MMC host:
   - sdhci-msm: Make it optional to wait for signal level changes
   - sdhci: Avoid swiotlb buffer being full"

* tag 'mmc-v4.15-2' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc:
  mmc: core: prepend 0x to OCR entry in sysfs
  mmc: core: prepend 0x to pre_eol_info entry in sysfs
  mmc: sdhci: Avoid swiotlb buffer being full
  mmc: sdhci-msm: Optionally wait for signal level changes
  mmc: block: Ensure that debugfs files are removed
  mmc: core: Do not leave the block driver in a suspended state
  mmc: block: Check return value of blk_get_request()
  mmc: block: Fix missing blk_put_request()
parents 5dc9cbc4 c892b0d8
Loading
Loading
Loading
Loading
+59 −8
Original line number Diff line number Diff line
@@ -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);
+3 −0
Original line number Diff line number Diff line
@@ -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;
}

+1 −0
Original line number Diff line number Diff line
@@ -314,4 +314,5 @@ void mmc_add_card_debugfs(struct mmc_card *card)
void mmc_remove_card_debugfs(struct mmc_card *card)
{
	debugfs_remove_recursive(card->debugfs_root);
	card->debugfs_root = NULL;
}
+2 −2
Original line number Diff line number Diff line
@@ -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,
+1 −1
Original line number Diff line number Diff line
@@ -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,
Loading