Commit 64e0a080 authored by Moudy Ho's avatar Moudy Ho Committed by Hans Verkuil
Browse files

media: platform: mtk-mdp3: fix error handling in mdp_cmdq_send()



Increase and refine the goto label in mdp_cmdq_send() to avoid
double free and facilitate traceability.
Also, remove redundant work queue event in blocking function
mdp_cmdq_send().

Fixes: 61890cca ("media: platform: mtk-mdp3: add MediaTek MDP3 driver")
Signed-off-by: default avatarMoudy Ho <moudy.ho@mediatek.com>
Reviewed-by: default avatarAngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Signed-off-by: default avatarHans Verkuil <hverkuil-cisco@xs4all.nl>
parent fe4c63c1
Loading
Loading
Loading
Loading
+26 −21
Original line number Diff line number Diff line
@@ -252,10 +252,9 @@ static int mdp_cmdq_pkt_create(struct cmdq_client *client, struct cmdq_pkt *pkt,
	dma_addr_t dma_addr;

	pkt->va_base = kzalloc(size, GFP_KERNEL);
	if (!pkt->va_base) {
		kfree(pkt);
	if (!pkt->va_base)
		return -ENOMEM;
	}

	pkt->buf_size = size;
	pkt->cl = (void *)client;

@@ -368,25 +367,30 @@ int mdp_cmdq_send(struct mdp_dev *mdp, struct mdp_cmdq_param *param)
	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
	if (!cmd) {
		ret = -ENOMEM;
		goto err_cmdq_data;
		goto err_cancel_job;
	}

	if (mdp_cmdq_pkt_create(mdp->cmdq_clt, &cmd->pkt, SZ_16K)) {
		ret = -ENOMEM;
		goto err_cmdq_data;
	}
	ret = mdp_cmdq_pkt_create(mdp->cmdq_clt, &cmd->pkt, SZ_16K);
	if (ret)
		goto err_free_cmd;

	comps = kcalloc(param->config->num_components, sizeof(*comps),
			GFP_KERNEL);
	if (!comps) {
		ret = -ENOMEM;
		goto err_cmdq_data;
		goto err_destroy_pkt;
	}

	path = kzalloc(sizeof(*path), GFP_KERNEL);
	if (!path) {
		ret = -ENOMEM;
		goto err_cmdq_data;
		goto err_free_comps;
	}

	ret = mtk_mutex_prepare(mdp->mdp_mutex[MDP_PIPE_RDMA0]);
	if (ret) {
		dev_err(dev, "Fail to enable mutex clk\n");
		goto err_free_path;
	}

	path->mdp_dev = mdp;
@@ -406,15 +410,13 @@ int mdp_cmdq_send(struct mdp_dev *mdp, struct mdp_cmdq_param *param)
	ret = mdp_path_ctx_init(mdp, path);
	if (ret) {
		dev_err(dev, "mdp_path_ctx_init error\n");
		goto err_cmdq_data;
		goto err_free_path;
	}

	mtk_mutex_prepare(mdp->mdp_mutex[MDP_PIPE_RDMA0]);

	ret = mdp_path_config(mdp, cmd, path);
	if (ret) {
		dev_err(dev, "mdp_path_config error\n");
		goto err_cmdq_data;
		goto err_free_path;
	}
	cmdq_pkt_finalize(&cmd->pkt);

@@ -433,7 +435,7 @@ int mdp_cmdq_send(struct mdp_dev *mdp, struct mdp_cmdq_param *param)
	ret = mdp_comp_clocks_on(&mdp->pdev->dev, cmd->comps, cmd->num_comps);
	if (ret) {
		dev_err(dev, "comp %d failed to enable clock!\n", ret);
		goto err_clock_off;
		goto err_free_path;
	}

	dma_sync_single_for_device(mdp->cmdq_clt->chan->mbox->dev,
@@ -450,17 +452,20 @@ int mdp_cmdq_send(struct mdp_dev *mdp, struct mdp_cmdq_param *param)
	return 0;

err_clock_off:
	mtk_mutex_unprepare(mdp->mdp_mutex[MDP_PIPE_RDMA0]);
	mdp_comp_clocks_off(&mdp->pdev->dev, cmd->comps,
			    cmd->num_comps);
err_cmdq_data:
err_free_path:
	mtk_mutex_unprepare(mdp->mdp_mutex[MDP_PIPE_RDMA0]);
	kfree(path);
	atomic_dec(&mdp->job_count);
	wake_up(&mdp->callback_wq);
	if (cmd && cmd->pkt.buf_size > 0)
		mdp_cmdq_pkt_destroy(&cmd->pkt);
err_free_comps:
	kfree(comps);
err_destroy_pkt:
	mdp_cmdq_pkt_destroy(&cmd->pkt);
err_free_cmd:
	kfree(cmd);
err_cancel_job:
	atomic_dec(&mdp->job_count);

	return ret;
}
EXPORT_SYMBOL_GPL(mdp_cmdq_send);