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

Commit cf00cd3f authored by Asutosh Das's avatar Asutosh Das Committed by Matt Wagantall
Browse files

mmc: block: add support for partition switch



There could be a switch of partition while RPMB access.
RPMB thread would then hand-off the control to mmc-cmdq-thread
in the following state:
	- partition set to RPMB in card
	- CMDQ mode disabled in card
	- Controller in halt state

When the next request is received, the following has to be done
	- switch partition to the current partition
	- enable CMDQ in card
	- unhalt controller

Change-Id: I9eca350572fd88476dfee9642696a223c5cd7ada
Signed-off-by: default avatarAsutosh Das <asutoshd@codeaurora.org>
Signed-off-by: default avatarVenkat Gopalakrishnan <venkatg@codeaurora.org>
parent b9f8507e
Loading
Loading
Loading
Loading
+46 −1
Original line number Diff line number Diff line
@@ -2862,6 +2862,51 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc)
	return 0;
}

static inline int mmc_blk_cmdq_part_switch(struct mmc_card *card,
				      struct mmc_blk_data *md)
{
	struct mmc_blk_data *main_md = mmc_get_drvdata(card);
	struct mmc_host *host = card->host;
	struct mmc_cmdq_context_info *ctx = &host->cmdq_ctx;
	u8 part_config = card->ext_csd.part_config;

	if ((main_md->part_curr == md->part_type) &&
	    (card->part_curr == md->part_type))
		return 0;

	WARN_ON(!((card->host->caps2 & MMC_CAP2_CMD_QUEUE) &&
		 card->ext_csd.cmdq_support &&
		 (md->flags & MMC_BLK_CMD_QUEUE)));

	if (!test_bit(CMDQ_STATE_HALT, &ctx->curr_state))
		WARN_ON(mmc_cmdq_halt(host, true));

	/* disable CQ mode in card */
	if (mmc_card_cmdq(card)) {
		WARN_ON(mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
				 EXT_CSD_CMDQ, 0,
				  card->ext_csd.generic_cmd6_time));
		mmc_card_clr_cmdq(card);
	}

	part_config &= ~EXT_CSD_PART_CONFIG_ACC_MASK;
	part_config |= md->part_type;

	WARN_ON(mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
			 EXT_CSD_PART_CONFIG, part_config,
			  card->ext_csd.part_time));

	card->ext_csd.part_config = part_config;
	card->part_curr = md->part_type;

	main_md->part_curr = md->part_type;

	WARN_ON(mmc_blk_cmdq_switch(card, md, true));
	WARN_ON(mmc_cmdq_halt(host, false));

	return 0;
}

static int mmc_blk_cmdq_issue_rq(struct mmc_queue *mq, struct request *req)
{
	int ret;
@@ -2870,7 +2915,7 @@ static int mmc_blk_cmdq_issue_rq(struct mmc_queue *mq, struct request *req)
	unsigned int cmd_flags = req ? req->cmd_flags : 0;

	mmc_claim_host(card->host);
	ret = mmc_blk_part_switch(card, md);
	ret = mmc_blk_cmdq_part_switch(card, md);
	if (ret) {
		pr_err("%s: %s: partition switch failed %d\n",
				md->disk->disk_name, __func__, ret);