mmc: cmdq: add clock scaling for CMDQ mode
This change adds clock scaling ability to command-queueing
mode, it does so by adding next logic:
* Statistics collection for CMDQ data path
* Empty the queue and Halt it before frequency change
* Scale from data path in case host claiming is not possible
Change-Id: I53a323b55df4d7c27e3ee3426ee4e856e533522c
Signed-off-by: Talel Shenhar <tatias@codeaurora.org>
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index 098bf49..7ffa94d 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -3146,6 +3146,12 @@
struct mmc_cmdq_req *mc_rq;
int ret = 0;
+ if (host->clk_scaling.enable) {
+ mmc_deferred_scaling(host);
+ mmc_cmdq_clk_scaling_start_busy(host, true);
+ BUG_ON(test_and_set_bit(req->tag,
+ &host->cmdq_ctx.data_active_reqs));
+ }
BUG_ON((req->tag < 0) || (req->tag > card->ext_csd.cmdq_depth));
BUG_ON(test_and_set_bit(req->tag, &host->cmdq_ctx.active_reqs));
@@ -3360,6 +3366,7 @@
struct mmc_cmdq_req *cmdq_req = &mq_rq->cmdq_req;
struct mmc_queue *mq = (struct mmc_queue *)rq->q->queuedata;
int err = 0;
+ bool is_dcmd = false;
if (mrq->cmd && mrq->cmd->error)
err = mrq->cmd->error;
@@ -3370,6 +3377,14 @@
BUG_ON(!test_and_clear_bit(cmdq_req->tag,
&ctx_info->active_reqs));
+ if (host->clk_scaling.enable) {
+ if (cmdq_req->cmdq_req_flags & DCMD)
+ is_dcmd = true;
+ else
+ BUG_ON(!test_and_clear_bit(cmdq_req->tag,
+ &ctx_info->data_active_reqs));
+ }
+
mmc_cmdq_post_req(host, mrq, err);
if (err) {
pr_err("%s: %s: txfr error: %d\n", mmc_hostname(mrq->host),
@@ -3394,11 +3409,16 @@
blk_end_request(rq, err, cmdq_req->data.bytes_xfered);
out:
+
+ mmc_cmdq_clk_scaling_stop_busy(host, true, is_dcmd);
if (!test_bit(CMDQ_STATE_ERR, &ctx_info->curr_state) &&
test_and_clear_bit(0, &ctx_info->req_starved))
blk_run_queue(mq->queue);
mmc_put_card(host->card);
+ if (!ctx_info->active_reqs)
+ wake_up_interruptible(&host->cmdq_ctx.queue_empty_wq);
+
if (blk_queue_stopped(mq->queue) && !ctx_info->active_reqs)
complete(&mq->cmdq_shutdown_complete);
return;